@memberjunction/server 6.2.0-edge.4 → 6.2.0-edge.5
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 +20 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/SessionJanitor.d.ts +91 -30
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
- package/dist/agentSessions/SessionJanitor.js +311 -81
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/agentSessions/SessionManager.d.ts +5 -1
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +13 -1
- package/dist/agentSessions/SessionManager.js.map +1 -1
- package/dist/apiRoot.d.ts +32 -0
- package/dist/apiRoot.d.ts.map +1 -0
- package/dist/apiRoot.js +67 -0
- package/dist/apiRoot.js.map +1 -0
- package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
- package/dist/auth/AuthProviderCatalogRouter.js +25 -0
- package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
- package/dist/auth/LoginScreenEngine.d.ts +22 -0
- package/dist/auth/LoginScreenEngine.d.ts.map +1 -0
- package/dist/auth/LoginScreenEngine.js +57 -0
- package/dist/auth/LoginScreenEngine.js.map +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +1 -0
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.js +3 -2
- package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
- package/dist/config.d.ts +136 -22
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +43 -4
- package/dist/config.js.map +1 -1
- package/dist/coreRoutes.d.ts +29 -0
- package/dist/coreRoutes.d.ts.map +1 -0
- package/dist/coreRoutes.js +142 -0
- package/dist/coreRoutes.js.map +1 -0
- package/dist/generated/graphql-schemas/__mj.d.ts +369 -3
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +1750 -7
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/CacheInvalidationResolver.d.ts +43 -8
- package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
- package/dist/generic/CacheInvalidationResolver.js +59 -19
- package/dist/generic/CacheInvalidationResolver.js.map +1 -1
- package/dist/generic/PushStatusResolver.js +1 -1
- package/dist/generic/PushStatusResolver.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +103 -44
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +264 -305
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +12 -0
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/globalCors.d.ts +33 -0
- package/dist/globalCors.d.ts.map +1 -0
- package/dist/globalCors.js +58 -0
- package/dist/globalCors.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +112 -160
- package/dist/index.js.map +1 -1
- package/dist/multiTenancy/index.d.ts.map +1 -1
- package/dist/multiTenancy/index.js +22 -2
- package/dist/multiTenancy/index.js.map +1 -1
- package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts.map +1 -1
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js +2 -1
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js.map +1 -1
- package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts.map +1 -1
- package/dist/realtimeSessions/RealtimeVerifyRouter.js +2 -1
- package/dist/realtimeSessions/RealtimeVerifyRouter.js.map +1 -1
- package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts +100 -0
- package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts.map +1 -0
- package/dist/realtimeSessions/RecordingAssemblyScheduler.js +173 -0
- package/dist/realtimeSessions/RecordingAssemblyScheduler.js.map +1 -0
- package/dist/realtimeSessions/index.d.ts +2 -0
- package/dist/realtimeSessions/index.d.ts.map +1 -1
- package/dist/realtimeSessions/index.js +2 -0
- package/dist/realtimeSessions/index.js.map +1 -1
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts +30 -0
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -0
- package/dist/realtimeSessions/ownedRealtimeSession.js +47 -0
- package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -0
- package/dist/realtimeSessions/sessionAccess.d.ts +6 -0
- package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
- package/dist/realtimeSessions/sessionAccess.js +7 -3
- package/dist/realtimeSessions/sessionAccess.js.map +1 -1
- package/dist/resolvers/ArtifactFileResolver.d.ts +5 -1
- package/dist/resolvers/ArtifactFileResolver.d.ts.map +1 -1
- package/dist/resolvers/ArtifactFileResolver.js +9 -7
- package/dist/resolvers/ArtifactFileResolver.js.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.d.ts +8 -4
- package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.js +6 -6
- package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
- package/dist/resolvers/DatasetResolver.d.ts +24 -3
- package/dist/resolvers/DatasetResolver.d.ts.map +1 -1
- package/dist/resolvers/DatasetResolver.js +57 -8
- package/dist/resolvers/DatasetResolver.js.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts +2 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.js +3 -2
- package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts +18 -3
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.js +100 -35
- package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.d.ts +82 -11
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +279 -101
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.d.ts +33 -7
- package/dist/resolvers/GetDataContextDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.js +117 -38
- package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +6 -3
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +4 -2
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/QueryResolver.d.ts +2 -0
- package/dist/resolvers/QueryResolver.d.ts.map +1 -1
- package/dist/resolvers/QueryResolver.js +13 -0
- package/dist/resolvers/QueryResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +2 -8
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +10 -26
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +35 -6
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts +12 -1
- package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts.map +1 -1
- package/dist/resolvers/SearchKnowledgeStreamResolver.js +15 -2
- package/dist/resolvers/SearchKnowledgeStreamResolver.js.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.js +2 -3
- package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
- package/dist/resolvers/TaskGraphFrameResolver.d.ts +2 -1
- package/dist/resolvers/TaskGraphFrameResolver.d.ts.map +1 -1
- package/dist/resolvers/TaskGraphFrameResolver.js +28 -1
- package/dist/resolvers/TaskGraphFrameResolver.js.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.d.ts +24 -0
- package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.js +65 -13
- package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.d.ts +19 -2
- package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.js +102 -24
- package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
- package/dist/resolvers/agent-run-data-guard.d.ts +31 -0
- package/dist/resolvers/agent-run-data-guard.d.ts.map +1 -0
- package/dist/resolvers/agent-run-data-guard.js +72 -0
- package/dist/resolvers/agent-run-data-guard.js.map +1 -0
- package/dist/rest/RealtimeRecordingHandler.d.ts +49 -0
- package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -0
- package/dist/rest/RealtimeRecordingHandler.js +383 -0
- package/dist/rest/RealtimeRecordingHandler.js.map +1 -0
- package/dist/rest/ViewOperationsHandler.d.ts +3 -1
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +21 -12
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/rest/setupRESTEndpoints.d.ts +6 -0
- package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
- package/dist/rest/setupRESTEndpoints.js +6 -0
- package/dist/rest/setupRESTEndpoints.js.map +1 -1
- package/dist/serverExtensionReservedRoots.d.ts +12 -10
- package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
- package/dist/serverExtensionReservedRoots.js +14 -17
- package/dist/serverExtensionReservedRoots.js.map +1 -1
- package/dist/services/MJStorageBlobStore.d.ts +8 -1
- package/dist/services/MJStorageBlobStore.d.ts.map +1 -1
- package/dist/services/MJStorageBlobStore.js +25 -19
- package/dist/services/MJStorageBlobStore.js.map +1 -1
- package/dist/services/StartTaskGraphDispatcher.js +2 -2
- package/dist/services/StartTaskGraphDispatcher.js.map +1 -1
- package/dist/services/TaskGraphActionRunner.d.ts +5 -3
- package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphActionRunner.js +27 -5
- package/dist/services/TaskGraphActionRunner.js.map +1 -1
- package/dist/services/TaskGraphAgentRunner.d.ts +14 -2
- package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphAgentRunner.js +157 -9
- package/dist/services/TaskGraphAgentRunner.js.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.d.ts +54 -2
- package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.js +598 -15
- package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
- package/dist/sharedCache.d.ts.map +1 -1
- package/dist/sharedCache.js +3 -0
- package/dist/sharedCache.js.map +1 -1
- package/package.json +99 -98
- package/src/__tests__/DatasetResolver.itemFilters.test.ts +201 -0
- package/src/__tests__/EntityRecordNameResolver.rowSecurity.test.ts +152 -0
- package/src/__tests__/FetchEntityVectorsResolver.test.ts +163 -15
- package/src/__tests__/FileResolver.storageAccess.test.ts +562 -0
- package/src/__tests__/GetDataContextDataResolver.sqlItems.test.ts +416 -0
- package/src/__tests__/ListOperationsResolver.adhocScreen.test.ts +137 -0
- package/src/__tests__/LoginScreenEngine.test.ts +86 -0
- package/src/__tests__/MJStorageBlobStore.storageGate.test.ts +63 -0
- package/src/__tests__/RecordingAssemblyScheduler.test.ts +178 -0
- package/src/__tests__/ResolverBase.adhocReadScope.test.ts +133 -2
- package/src/__tests__/ResolverBase.balancedClause.test.ts +155 -0
- package/src/__tests__/ResolverBase.clauseUnscopedRead.test.ts +127 -0
- package/src/__tests__/ResolverBase.clientOldValues.test.ts +209 -6
- package/src/__tests__/ResolverBase.filterEscaping.test.ts +5 -2
- package/src/__tests__/RunAIAgentResolver.branch.test.ts +1 -0
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +5 -3
- package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +258 -0
- package/src/__tests__/RunViewResolver.cacheCheckScreen.test.ts +165 -0
- package/src/__tests__/SearchKnowledgeStreamResolver.test.ts +161 -0
- package/src/__tests__/SessionJanitor.test.ts +365 -10
- package/src/__tests__/SessionManager.test.ts +27 -0
- package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +25 -0
- package/src/__tests__/TaskGraphAgentRunner.test.ts +266 -0
- package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +356 -22
- package/src/__tests__/TaskGraphFrameResolver.test.ts +22 -0
- package/src/__tests__/TestQuerySQLResolver.test.ts +274 -0
- package/src/__tests__/TransactionGroupResolver.refusals.test.ts +98 -1
- package/src/__tests__/UpdateMJDataContextItem.oldValues.test.ts +220 -0
- package/src/__tests__/ViewOperationsHandler.clauseScreen.test.ts +157 -0
- package/src/__tests__/agent-run-data-guard.test.ts +130 -0
- package/src/__tests__/apiRootBoot.test.ts +202 -0
- package/src/__tests__/cacheInvalidationRecordData.test.ts +64 -0
- package/src/__tests__/conversationRunEvents.test.ts +56 -14
- package/src/__tests__/globalCors.test.ts +217 -0
- package/src/__tests__/multiTenancy.postgresRewrite.test.ts +181 -0
- package/src/__tests__/multiTenancy.security.test.ts +51 -0
- package/src/__tests__/multiTenancy.test.ts +1 -1
- package/src/__tests__/ownedRealtimeSession.test.ts +39 -0
- package/src/__tests__/pushStatusResolver.filter.test.ts +7 -0
- package/src/__tests__/realtimeRecordingHandler.test.ts +652 -0
- package/src/__tests__/serverExtensionHostOverlay.test.ts +66 -0
- package/src/__tests__/serverExtensionReservedRoots.test.ts +11 -98
- package/src/__tests__/sharedCache.test.ts +5 -3
- package/src/agentSessions/SessionJanitor.ts +369 -93
- package/src/agentSessions/SessionManager.ts +13 -1
- package/src/apiRoot.ts +78 -0
- package/src/auth/AuthProviderCatalogRouter.ts +26 -0
- package/src/auth/LoginScreenEngine.ts +50 -0
- package/src/auth/index.ts +1 -0
- package/src/auth/magicLink/MagicLinkRouter.ts +3 -2
- package/src/config.ts +46 -5
- package/src/coreRoutes.ts +166 -0
- package/src/generated/graphql-schemas/__mj.ts +1273 -10
- package/src/generic/CacheInvalidationResolver.ts +73 -18
- package/src/generic/PushStatusResolver.ts +1 -1
- package/src/generic/ResolverBase.ts +304 -325
- package/src/generic/RunViewResolver.ts +17 -0
- package/src/globalCors.ts +71 -0
- package/src/index.ts +116 -174
- package/src/multiTenancy/index.ts +24 -2
- package/src/realtimeSessions/RealtimeSessionVerificationService.ts +2 -1
- package/src/realtimeSessions/RealtimeVerifyRouter.ts +2 -1
- package/src/realtimeSessions/RecordingAssemblyScheduler.ts +234 -0
- package/src/realtimeSessions/index.ts +2 -0
- package/src/realtimeSessions/ownedRealtimeSession.ts +55 -0
- package/src/realtimeSessions/sessionAccess.ts +7 -3
- package/src/resolvers/ArtifactFileResolver.ts +9 -8
- package/src/resolvers/ConversationRunEventsResolver.ts +15 -11
- package/src/resolvers/DatasetResolver.ts +70 -10
- package/src/resolvers/EntityRecordNameResolver.ts +3 -2
- package/src/resolvers/FetchEntityVectorsResolver.ts +121 -39
- package/src/resolvers/FileResolver.ts +321 -106
- package/src/resolvers/GetDataContextDataResolver.ts +139 -41
- package/src/resolvers/GetDataResolver.ts +6 -3
- package/src/resolvers/IntegrationDiscoveryResolver.ts +4 -2
- package/src/resolvers/QueryResolver.ts +11 -0
- package/src/resolvers/RealtimeClientSessionResolver.ts +10 -33
- package/src/resolvers/RunAIAgentResolver.ts +39 -4
- package/src/resolvers/SearchKnowledgeStreamResolver.ts +19 -3
- package/src/resolvers/SqlLoggingConfigResolver.ts +2 -4
- package/src/resolvers/TaskGraphFrameResolver.ts +33 -1
- package/src/resolvers/TestQuerySQLResolver.ts +68 -13
- package/src/resolvers/TransactionGroupResolver.ts +131 -27
- package/src/resolvers/__tests__/GetDataResolver.validation.test.ts +95 -0
- package/src/resolvers/agent-run-data-guard.ts +89 -0
- package/src/rest/RealtimeRecordingHandler.ts +464 -0
- package/src/rest/ViewOperationsHandler.ts +29 -13
- package/src/rest/setupRESTEndpoints.ts +6 -0
- package/src/serverExtensionReservedRoots.ts +14 -17
- package/src/services/MJStorageBlobStore.ts +31 -30
- package/src/services/StartTaskGraphDispatcher.ts +2 -2
- package/src/services/TaskGraphActionRunner.ts +25 -5
- package/src/services/TaskGraphAgentRunner.ts +188 -11
- package/src/services/TaskGraphContinuationDeliverer.ts +704 -14
- package/src/sharedCache.ts +3 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Per-session timers that assemble a client-direct realtime recording from its shard ledger
|
|
3
|
+
* off the request path.
|
|
4
|
+
*
|
|
5
|
+
* The recording REST routes only record shards and the terminal signal; they never decode. When a route
|
|
6
|
+
* learns a session is ready (every expected shard present) it asks for an assembly now; when shards are
|
|
7
|
+
* missing it asks for one after the grace period, forced to `Partial`. This scheduler turns those requests
|
|
8
|
+
* into at most one pending timer and at most one running assembly per session in this process.
|
|
9
|
+
*
|
|
10
|
+
* Correctness across processes does not depend on it: every run starts with the ledger's atomic
|
|
11
|
+
* `ClaimAssembly`, so of two instances (or two timers) only the claim winner assembles. The per-session
|
|
12
|
+
* guard here only avoids wasted claims. A run that dies with the process leaves the session `Assembling`,
|
|
13
|
+
* and the session janitor's stale re-claim is the backstop for that and for any request dropped here.
|
|
14
|
+
*
|
|
15
|
+
* @module @memberjunction/server/realtimeSessions
|
|
16
|
+
*/
|
|
17
|
+
import { DatabaseProviderBase, UserInfo } from '@memberjunction/core';
|
|
18
|
+
import { BaseSingleton, IShutdownable } from '@memberjunction/global';
|
|
19
|
+
import { AssembleRealtimeRecordingInput, AssembleRealtimeRecordingOutcome, IRealtimeRecordingLedger } from '@memberjunction/ai-agents';
|
|
20
|
+
/** A cancellable one-shot timer. */
|
|
21
|
+
export interface RecordingAssemblyTimer {
|
|
22
|
+
Cancel(): void;
|
|
23
|
+
}
|
|
24
|
+
/** Time source of the scheduler; injectable so tests can drive it. */
|
|
25
|
+
export interface RecordingAssemblyClock {
|
|
26
|
+
/** Milliseconds since the epoch. */
|
|
27
|
+
Now(): number;
|
|
28
|
+
/** Runs `callback` once after `delayMs`. The timer must not keep the process alive. */
|
|
29
|
+
StartTimer(callback: () => void, delayMs: number): RecordingAssemblyTimer;
|
|
30
|
+
}
|
|
31
|
+
/** The narrow scheduling contract the recording routes depend on. */
|
|
32
|
+
export interface IRecordingAssemblyScheduler {
|
|
33
|
+
/**
|
|
34
|
+
* Requests an assembly of `sessionID` after `delayMs`. `forcePartial` assembles what exists even when
|
|
35
|
+
* shards are missing (the grace period ran out). See {@link RecordingAssemblyScheduler.ScheduleAssembly}.
|
|
36
|
+
*/
|
|
37
|
+
ScheduleAssembly(sessionID: string, delayMs: number, forcePartial: boolean): void;
|
|
38
|
+
}
|
|
39
|
+
/** What {@link RecordingAssemblyScheduler.Start} needs. */
|
|
40
|
+
export interface RecordingAssemblySchedulerOptions {
|
|
41
|
+
/** The server's own provider; assembly is server-owned background work, not a request. */
|
|
42
|
+
Provider: DatabaseProviderBase;
|
|
43
|
+
/** The user assembly runs as (the system user). */
|
|
44
|
+
SystemUser: UserInfo;
|
|
45
|
+
/** Grace before a `Deferred` (incomplete) assembly is retried as forced `Partial`. */
|
|
46
|
+
GraceMs: () => number;
|
|
47
|
+
/** Defaults to {@link SqlRealtimeRecordingLedger}. */
|
|
48
|
+
CreateLedger?: (provider: DatabaseProviderBase, contextUser: UserInfo) => IRealtimeRecordingLedger;
|
|
49
|
+
/** Defaults to {@link AssembleRealtimeRecordingFromLedger}. */
|
|
50
|
+
Assemble?: (input: AssembleRealtimeRecordingInput) => Promise<AssembleRealtimeRecordingOutcome>;
|
|
51
|
+
/** Defaults to `Date.now` and unref'd `setTimeout`. */
|
|
52
|
+
Clock?: RecordingAssemblyClock;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Process-wide scheduler of recording assemblies (see the file overview). Call {@link Start} once at
|
|
56
|
+
* server startup; requests made before it (or after {@link Shutdown}) are logged and dropped, leaving the
|
|
57
|
+
* session to the janitor.
|
|
58
|
+
*/
|
|
59
|
+
export declare class RecordingAssemblyScheduler extends BaseSingleton<RecordingAssemblyScheduler> implements IShutdownable, IRecordingAssemblyScheduler {
|
|
60
|
+
private _options;
|
|
61
|
+
private _registered;
|
|
62
|
+
/** Pending timers keyed by lowercase session id. */
|
|
63
|
+
private readonly pending;
|
|
64
|
+
/** Lowercase ids of sessions with an assembly running in this process. */
|
|
65
|
+
private readonly running;
|
|
66
|
+
/** Sessions asked for again while running, with the ForcePartial to re-run with. */
|
|
67
|
+
private readonly rerun;
|
|
68
|
+
protected constructor();
|
|
69
|
+
/** Process-wide singleton accessor. */
|
|
70
|
+
static get Instance(): RecordingAssemblyScheduler;
|
|
71
|
+
/** Identifier surfaced in graceful-shutdown logs. */
|
|
72
|
+
readonly ShutdownName = "RecordingAssemblyScheduler";
|
|
73
|
+
/** Configures the scheduler and enables it; calling again replaces the configuration. */
|
|
74
|
+
Start(options: RecordingAssemblySchedulerOptions): void;
|
|
75
|
+
/**
|
|
76
|
+
* Requests an assembly of `sessionID` after `delayMs`. One pending timer per session: a request
|
|
77
|
+
* replaces the pending one only when it would fire sooner (at the same time, the merged request keeps
|
|
78
|
+
* `forcePartial` if either had it). A timer that fires while the session's previous run is still going
|
|
79
|
+
* is remembered and run right after it, never alongside it.
|
|
80
|
+
*
|
|
81
|
+
* Trade-off: a sooner un-forced request replaces a pending forced one. If that run comes back
|
|
82
|
+
* `Deferred` (still incomplete), the forced `Partial` is re-scheduled a full grace from then, so a
|
|
83
|
+
* forced Partial can land up to ~2× the grace after the first terminal signal. Accepted: the sooner
|
|
84
|
+
* run completes the recording outright whenever the missing shards did arrive.
|
|
85
|
+
*/
|
|
86
|
+
ScheduleAssembly(sessionID: string, delayMs: number, forcePartial: boolean): void;
|
|
87
|
+
/**
|
|
88
|
+
* Cancels every pending timer and stops accepting requests until the next {@link Start}. A running
|
|
89
|
+
* assembly is not awaited: if the process exits under it, the session stays `Assembling` and the
|
|
90
|
+
* janitor's stale re-claim finishes it. Idempotent.
|
|
91
|
+
*/
|
|
92
|
+
Shutdown(): void;
|
|
93
|
+
private onTimer;
|
|
94
|
+
/** Runs the session's assembly, then any re-run requested meanwhile. Never rejects. */
|
|
95
|
+
private runUntilSettled;
|
|
96
|
+
/** One claim + assembly. Logs every failure with the session id; never throws. */
|
|
97
|
+
private runOnce;
|
|
98
|
+
private handleOutcome;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=RecordingAssemblyScheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecordingAssemblyScheduler.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/RecordingAssemblyScheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,oBAAoB,EAAuB,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,aAAa,EAAoB,MAAM,wBAAwB,CAAC;AACxF,OAAO,EACkC,8BAA8B,EAAE,gCAAgC,EACrG,wBAAwB,EAC3B,MAAM,2BAA2B,CAAC;AAEnC,oCAAoC;AACpC,MAAM,WAAW,sBAAsB;IACnC,MAAM,IAAI,IAAI,CAAC;CAClB;AAED,sEAAsE;AACtE,MAAM,WAAW,sBAAsB;IACnC,oCAAoC;IACpC,GAAG,IAAI,MAAM,CAAC;IACd,uFAAuF;IACvF,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,sBAAsB,CAAC;CAC7E;AAED,qEAAqE;AACrE,MAAM,WAAW,2BAA2B;IACxC;;;OAGG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;CACrF;AAED,2DAA2D;AAC3D,MAAM,WAAW,iCAAiC;IAC9C,0FAA0F;IAC1F,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,mDAAmD;IACnD,UAAU,EAAE,QAAQ,CAAC;IACrB,sFAAsF;IACtF,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,sDAAsD;IACtD,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,oBAAoB,EAAE,WAAW,EAAE,QAAQ,KAAK,wBAAwB,CAAC;IACnG,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,8BAA8B,KAAK,OAAO,CAAC,gCAAgC,CAAC,CAAC;IAChG,uDAAuD;IACvD,KAAK,CAAC,EAAE,sBAAsB,CAAC;CAClC;AAiBD;;;;GAIG;AACH,qBAAa,0BAA2B,SAAQ,aAAa,CAAC,0BAA0B,CAAE,YAAW,aAAa,EAAE,2BAA2B;IAC3I,OAAO,CAAC,QAAQ,CAA4D;IAC5E,OAAO,CAAC,WAAW,CAAS;IAC5B,oDAAoD;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsC;IAC9D,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,oFAAoF;IACpF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8B;IAEpD,SAAS;IAIT,uCAAuC;IACvC,WAAkB,QAAQ,IAAI,0BAA0B,CAEvD;IAED,qDAAqD;IACrD,SAAgB,YAAY,gCAAgC;IAE5D,yFAAyF;IAClF,KAAK,CAAC,OAAO,EAAE,iCAAiC,GAAG,IAAI;IAa9D;;;;;;;;;;OAUG;IACI,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,IAAI;IAqBxF;;;;OAIG;IACI,QAAQ,IAAI,IAAI;IASvB,OAAO,CAAC,OAAO;IAaf,uFAAuF;YACzE,eAAe;IAc7B,kFAAkF;YACpE,OAAO;IAuBrB,OAAO,CAAC,aAAa;CAkBxB"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Per-session timers that assemble a client-direct realtime recording from its shard ledger
|
|
3
|
+
* off the request path.
|
|
4
|
+
*
|
|
5
|
+
* The recording REST routes only record shards and the terminal signal; they never decode. When a route
|
|
6
|
+
* learns a session is ready (every expected shard present) it asks for an assembly now; when shards are
|
|
7
|
+
* missing it asks for one after the grace period, forced to `Partial`. This scheduler turns those requests
|
|
8
|
+
* into at most one pending timer and at most one running assembly per session in this process.
|
|
9
|
+
*
|
|
10
|
+
* Correctness across processes does not depend on it: every run starts with the ledger's atomic
|
|
11
|
+
* `ClaimAssembly`, so of two instances (or two timers) only the claim winner assembles. The per-session
|
|
12
|
+
* guard here only avoids wasted claims. A run that dies with the process leaves the session `Assembling`,
|
|
13
|
+
* and the session janitor's stale re-claim is the backstop for that and for any request dropped here.
|
|
14
|
+
*
|
|
15
|
+
* @module @memberjunction/server/realtimeSessions
|
|
16
|
+
*/
|
|
17
|
+
import { LogError, LogStatus } from '@memberjunction/core';
|
|
18
|
+
import { BaseSingleton, ShutdownRegistry } from '@memberjunction/global';
|
|
19
|
+
import { AssembleRealtimeRecordingFromLedger, SqlRealtimeRecordingLedger, } from '@memberjunction/ai-agents';
|
|
20
|
+
const NODE_CLOCK = {
|
|
21
|
+
Now: () => Date.now(),
|
|
22
|
+
StartTimer: (callback, delayMs) => {
|
|
23
|
+
const handle = setTimeout(callback, delayMs);
|
|
24
|
+
handle.unref?.();
|
|
25
|
+
return { Cancel: () => clearTimeout(handle) };
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Process-wide scheduler of recording assemblies (see the file overview). Call {@link Start} once at
|
|
30
|
+
* server startup; requests made before it (or after {@link Shutdown}) are logged and dropped, leaving the
|
|
31
|
+
* session to the janitor.
|
|
32
|
+
*/
|
|
33
|
+
export class RecordingAssemblyScheduler extends BaseSingleton {
|
|
34
|
+
constructor() {
|
|
35
|
+
super();
|
|
36
|
+
this._options = null;
|
|
37
|
+
this._registered = false;
|
|
38
|
+
/** Pending timers keyed by lowercase session id. */
|
|
39
|
+
this.pending = new Map();
|
|
40
|
+
/** Lowercase ids of sessions with an assembly running in this process. */
|
|
41
|
+
this.running = new Set();
|
|
42
|
+
/** Sessions asked for again while running, with the ForcePartial to re-run with. */
|
|
43
|
+
this.rerun = new Map();
|
|
44
|
+
/** Identifier surfaced in graceful-shutdown logs. */
|
|
45
|
+
this.ShutdownName = 'RecordingAssemblyScheduler';
|
|
46
|
+
}
|
|
47
|
+
/** Process-wide singleton accessor. */
|
|
48
|
+
static get Instance() {
|
|
49
|
+
return super.getInstance();
|
|
50
|
+
}
|
|
51
|
+
/** Configures the scheduler and enables it; calling again replaces the configuration. */
|
|
52
|
+
Start(options) {
|
|
53
|
+
this._options = {
|
|
54
|
+
CreateLedger: (provider, contextUser) => new SqlRealtimeRecordingLedger(provider, contextUser),
|
|
55
|
+
Assemble: AssembleRealtimeRecordingFromLedger,
|
|
56
|
+
Clock: NODE_CLOCK,
|
|
57
|
+
...options,
|
|
58
|
+
};
|
|
59
|
+
if (!this._registered) {
|
|
60
|
+
ShutdownRegistry.Instance.Register(this);
|
|
61
|
+
this._registered = true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Requests an assembly of `sessionID` after `delayMs`. One pending timer per session: a request
|
|
66
|
+
* replaces the pending one only when it would fire sooner (at the same time, the merged request keeps
|
|
67
|
+
* `forcePartial` if either had it). A timer that fires while the session's previous run is still going
|
|
68
|
+
* is remembered and run right after it, never alongside it.
|
|
69
|
+
*
|
|
70
|
+
* Trade-off: a sooner un-forced request replaces a pending forced one. If that run comes back
|
|
71
|
+
* `Deferred` (still incomplete), the forced `Partial` is re-scheduled a full grace from then, so a
|
|
72
|
+
* forced Partial can land up to ~2× the grace after the first terminal signal. Accepted: the sooner
|
|
73
|
+
* run completes the recording outright whenever the missing shards did arrive.
|
|
74
|
+
*/
|
|
75
|
+
ScheduleAssembly(sessionID, delayMs, forcePartial) {
|
|
76
|
+
const options = this._options;
|
|
77
|
+
if (!options) {
|
|
78
|
+
LogError(`RecordingAssemblyScheduler: not running; dropped the assembly request for session ${sessionID} (the session janitor will assemble it)`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const key = sessionID.toLowerCase();
|
|
82
|
+
const dueAt = options.Clock.Now() + Math.max(0, delayMs);
|
|
83
|
+
const existing = this.pending.get(key);
|
|
84
|
+
if (existing && existing.DueAt < dueAt) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (existing && existing.DueAt === dueAt) {
|
|
88
|
+
existing.ForcePartial = existing.ForcePartial || forcePartial;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
existing?.Timer.Cancel();
|
|
92
|
+
const timer = options.Clock.StartTimer(() => this.onTimer(key, sessionID), dueAt - options.Clock.Now());
|
|
93
|
+
this.pending.set(key, { DueAt: dueAt, ForcePartial: forcePartial, Timer: timer });
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Cancels every pending timer and stops accepting requests until the next {@link Start}. A running
|
|
97
|
+
* assembly is not awaited: if the process exits under it, the session stays `Assembling` and the
|
|
98
|
+
* janitor's stale re-claim finishes it. Idempotent.
|
|
99
|
+
*/
|
|
100
|
+
Shutdown() {
|
|
101
|
+
for (const entry of this.pending.values()) {
|
|
102
|
+
entry.Timer.Cancel();
|
|
103
|
+
}
|
|
104
|
+
this.pending.clear();
|
|
105
|
+
this.rerun.clear();
|
|
106
|
+
this._options = null;
|
|
107
|
+
}
|
|
108
|
+
onTimer(key, sessionID) {
|
|
109
|
+
const entry = this.pending.get(key);
|
|
110
|
+
if (!entry) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
this.pending.delete(key);
|
|
114
|
+
if (this.running.has(key)) {
|
|
115
|
+
this.rerun.set(key, (this.rerun.get(key) ?? false) || entry.ForcePartial);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
void this.runUntilSettled(key, sessionID, entry.ForcePartial);
|
|
119
|
+
}
|
|
120
|
+
/** Runs the session's assembly, then any re-run requested meanwhile. Never rejects. */
|
|
121
|
+
async runUntilSettled(key, sessionID, forcePartial) {
|
|
122
|
+
this.running.add(key);
|
|
123
|
+
try {
|
|
124
|
+
let next = forcePartial;
|
|
125
|
+
while (next !== undefined) {
|
|
126
|
+
await this.runOnce(sessionID, next);
|
|
127
|
+
next = this.rerun.get(key);
|
|
128
|
+
this.rerun.delete(key);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
this.running.delete(key);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/** One claim + assembly. Logs every failure with the session id; never throws. */
|
|
136
|
+
async runOnce(sessionID, forcePartial) {
|
|
137
|
+
const options = this._options;
|
|
138
|
+
if (!options) {
|
|
139
|
+
LogStatus(`RecordingAssemblyScheduler: shut down before session ${sessionID} could assemble; the session janitor will assemble it`);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
const ledger = options.CreateLedger(options.Provider, options.SystemUser);
|
|
144
|
+
const version = await ledger.ClaimAssembly(sessionID, null);
|
|
145
|
+
if (version === null) {
|
|
146
|
+
LogStatus(`RecordingAssemblyScheduler: session ${sessionID} not claimable (assembled, assembling elsewhere, or failed); skipping`);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const outcome = await options.Assemble({
|
|
150
|
+
SessionID: sessionID, Version: version, Ledger: ledger,
|
|
151
|
+
ContextUser: options.SystemUser, Provider: options.Provider, ForcePartial: forcePartial,
|
|
152
|
+
});
|
|
153
|
+
this.handleOutcome(sessionID, version, outcome, options);
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
LogError(`RecordingAssemblyScheduler: assembly of session ${sessionID} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
handleOutcome(sessionID, version, outcome, options) {
|
|
160
|
+
if (outcome === 'Deferred') {
|
|
161
|
+
// Incomplete and not forced: give missing shards the grace period, then assemble what exists.
|
|
162
|
+
LogStatus(`RecordingAssemblyScheduler: session ${sessionID} (version ${version}) is missing shards; assembling as Partial after the grace period`);
|
|
163
|
+
this.ScheduleAssembly(sessionID, options.GraceMs(), true);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (outcome === 'Retry') {
|
|
167
|
+
LogError(`RecordingAssemblyScheduler: assembly of session ${sessionID} (version ${version}) hit a transient error; the session janitor re-claims it later`);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
LogStatus(`RecordingAssemblyScheduler: session ${sessionID} (version ${version}) assembly finished: ${outcome}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=RecordingAssemblyScheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecordingAssemblyScheduler.js","sourceRoot":"","sources":["../../src/realtimeSessions/RecordingAssemblyScheduler.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,4 +14,6 @@ export * from './sessionConfigStamps.js';
|
|
|
14
14
|
export * from './SessionVerificationPortsBase.js';
|
|
15
15
|
export * from './RealtimeSessionVerificationService.js';
|
|
16
16
|
export * from './RealtimeVerifyRouter.js';
|
|
17
|
+
export * from './ownedRealtimeSession.js';
|
|
18
|
+
export * from './RecordingAssemblyScheduler.js';
|
|
17
19
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,oBAAoB,CAAC;AACnC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,oBAAoB,CAAC;AACnC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC"}
|
|
@@ -14,4 +14,6 @@ export * from './sessionConfigStamps.js';
|
|
|
14
14
|
export * from './SessionVerificationPortsBase.js';
|
|
15
15
|
export * from './RealtimeSessionVerificationService.js';
|
|
16
16
|
export * from './RealtimeVerifyRouter.js';
|
|
17
|
+
export * from './ownedRealtimeSession.js';
|
|
18
|
+
export * from './RecordingAssemblyScheduler.js';
|
|
17
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/realtimeSessions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,oBAAoB,CAAC;AACnC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/realtimeSessions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,oBAAoB,CAAC;AACnC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The ownership gate for client-direct realtime session writes: the GraphQL mutations of
|
|
3
|
+
* `RealtimeClientSessionResolver` and the recording REST routes both load the session through
|
|
4
|
+
* {@link LoadOwnedRealtimeSession}, so "may this caller write to this session?" is decided in one place.
|
|
5
|
+
*
|
|
6
|
+
* @module @memberjunction/server/realtimeSessions
|
|
7
|
+
*/
|
|
8
|
+
import { IMetadataProvider, UserInfo } from '@memberjunction/core';
|
|
9
|
+
import type { MJAIAgentSessionEntity } from '@memberjunction/core-entities';
|
|
10
|
+
/** The session does not exist, or the caller cannot read it. */
|
|
11
|
+
export declare class RealtimeSessionNotFoundError extends Error {
|
|
12
|
+
readonly AgentSessionID: string;
|
|
13
|
+
constructor(AgentSessionID: string);
|
|
14
|
+
}
|
|
15
|
+
/** The session exists but belongs to another user. */
|
|
16
|
+
export declare class RealtimeSessionOwnershipError extends Error {
|
|
17
|
+
readonly AgentSessionID: string;
|
|
18
|
+
constructor(AgentSessionID: string);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Loads a session under the caller's identity and enforces ownership (`UserID === contextUser.ID`). It
|
|
22
|
+
* deliberately does NOT reject `Closed` sessions: the final channel-state flush and the recording terminal
|
|
23
|
+
* signal legitimately arrive after the session closed. A scoped-anonymous widget guest owns the session it
|
|
24
|
+
* minted, so the same check covers it; loading as the caller also applies the entity's row-level security.
|
|
25
|
+
*
|
|
26
|
+
* @throws RealtimeSessionNotFoundError when the row does not load
|
|
27
|
+
* @throws RealtimeSessionOwnershipError when the caller is not the owner (logged with both user ids)
|
|
28
|
+
*/
|
|
29
|
+
export declare function LoadOwnedRealtimeSession(agentSessionId: string, contextUser: UserInfo, provider: IMetadataProvider): Promise<MJAIAgentSessionEntity>;
|
|
30
|
+
//# sourceMappingURL=ownedRealtimeSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ownedRealtimeSession.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/ownedRealtimeSession.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,iBAAiB,EAAY,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE7E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAI5E,gEAAgE;AAChE,qBAAa,4BAA6B,SAAQ,KAAK;aACvB,cAAc,EAAE,MAAM;gBAAtB,cAAc,EAAE,MAAM;CAIrD;AAED,sDAAsD;AACtD,qBAAa,6BAA8B,SAAQ,KAAK;aACxB,cAAc,EAAE,MAAM;gBAAtB,cAAc,EAAE,MAAM;CAIrD;AAED;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC1C,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,QAAQ,EACrB,QAAQ,EAAE,iBAAiB,GAC5B,OAAO,CAAC,sBAAsB,CAAC,CAYjC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The ownership gate for client-direct realtime session writes: the GraphQL mutations of
|
|
3
|
+
* `RealtimeClientSessionResolver` and the recording REST routes both load the session through
|
|
4
|
+
* {@link LoadOwnedRealtimeSession}, so "may this caller write to this session?" is decided in one place.
|
|
5
|
+
*
|
|
6
|
+
* @module @memberjunction/server/realtimeSessions
|
|
7
|
+
*/
|
|
8
|
+
import { LogError } from '@memberjunction/core';
|
|
9
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
10
|
+
const SESSION_ENTITY = 'MJ: AI Agent Sessions';
|
|
11
|
+
/** The session does not exist, or the caller cannot read it. */
|
|
12
|
+
export class RealtimeSessionNotFoundError extends Error {
|
|
13
|
+
constructor(AgentSessionID) {
|
|
14
|
+
super(`Realtime session ${AgentSessionID} not found`);
|
|
15
|
+
this.AgentSessionID = AgentSessionID;
|
|
16
|
+
this.name = 'RealtimeSessionNotFoundError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** The session exists but belongs to another user. */
|
|
20
|
+
export class RealtimeSessionOwnershipError extends Error {
|
|
21
|
+
constructor(AgentSessionID) {
|
|
22
|
+
super('Not authorized: you do not own this realtime session');
|
|
23
|
+
this.AgentSessionID = AgentSessionID;
|
|
24
|
+
this.name = 'RealtimeSessionOwnershipError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Loads a session under the caller's identity and enforces ownership (`UserID === contextUser.ID`). It
|
|
29
|
+
* deliberately does NOT reject `Closed` sessions: the final channel-state flush and the recording terminal
|
|
30
|
+
* signal legitimately arrive after the session closed. A scoped-anonymous widget guest owns the session it
|
|
31
|
+
* minted, so the same check covers it; loading as the caller also applies the entity's row-level security.
|
|
32
|
+
*
|
|
33
|
+
* @throws RealtimeSessionNotFoundError when the row does not load
|
|
34
|
+
* @throws RealtimeSessionOwnershipError when the caller is not the owner (logged with both user ids)
|
|
35
|
+
*/
|
|
36
|
+
export async function LoadOwnedRealtimeSession(agentSessionId, contextUser, provider) {
|
|
37
|
+
const session = await provider.GetEntityObject(SESSION_ENTITY, contextUser);
|
|
38
|
+
if (!(await session.Load(agentSessionId))) {
|
|
39
|
+
throw new RealtimeSessionNotFoundError(agentSessionId);
|
|
40
|
+
}
|
|
41
|
+
if (!UUIDsEqual(session.UserID, contextUser.ID)) {
|
|
42
|
+
LogError(`LoadOwnedRealtimeSession: ownership check failed — user ${contextUser.ID} attempted to operate on session ${agentSessionId} owned by ${session.UserID}`);
|
|
43
|
+
throw new RealtimeSessionOwnershipError(agentSessionId);
|
|
44
|
+
}
|
|
45
|
+
return session;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=ownedRealtimeSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ownedRealtimeSession.js","sourceRoot":"","sources":["../../src/realtimeSessions/ownedRealtimeSession.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAqB,QAAQ,EAAY,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD,MAAM,cAAc,GAAG,uBAAuB,CAAC;AAE/C,gEAAgE;AAChE,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IACnD,YAA4B,cAAsB;QAC9C,KAAK,CAAC,oBAAoB,cAAc,YAAY,CAAC,CAAC;QAD9B,mBAAc,GAAd,cAAc,CAAQ;QAE9C,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;IAC/C,CAAC;CACJ;AAED,sDAAsD;AACtD,MAAM,OAAO,6BAA8B,SAAQ,KAAK;IACpD,YAA4B,cAAsB;QAC9C,KAAK,CAAC,sDAAsD,CAAC,CAAC;QADtC,mBAAc,GAAd,cAAc,CAAQ;QAE9C,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAC;IAChD,CAAC;CACJ;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC1C,cAAsB,EACtB,WAAqB,EACrB,QAA2B;IAE3B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAyB,cAAc,EAAE,WAAW,CAAC,CAAC;IACpG,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,4BAA4B,CAAC,cAAc,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC;QAC9C,QAAQ,CACJ,2DAA2D,WAAW,CAAC,EAAE,oCAAoC,cAAc,aAAa,OAAO,CAAC,MAAM,EAAE,CAC3J,CAAC;QACF,MAAM,IAAI,6BAA6B,CAAC,cAAc,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC"}
|
|
@@ -83,4 +83,10 @@ export interface LoadedSessionForAccess {
|
|
|
83
83
|
* which {@link AuthorizeSessionAccess} then treats as "no scope to match" (refused for a scoped caller).
|
|
84
84
|
*/
|
|
85
85
|
export declare function LoadSessionForAccess(agentSessionId: string, contextUser: UserInfo, provider: IMetadataProvider): Promise<LoadedSessionForAccess | null>;
|
|
86
|
+
/**
|
|
87
|
+
* Reads an already-loaded session's conversation `ExternalID` (the anonymous scope id) under `contextUser`;
|
|
88
|
+
* null when there is no conversation or it cannot be read (logged). For callers that loaded the session
|
|
89
|
+
* through another gate and only need the scope half of {@link AuthorizeSessionAccess}'s subject.
|
|
90
|
+
*/
|
|
91
|
+
export declare function LoadSessionConversationExternalID(session: MJAIAgentSessionEntity, contextUser: UserInfo, provider: IMetadataProvider): Promise<string | null>;
|
|
86
92
|
//# sourceMappingURL=sessionAccess.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionAccess.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/sessionAccess.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,iBAAiB,EAAY,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE7E,OAAO,KAAK,EAAE,sBAAsB,EAAwB,MAAM,+BAA+B,CAAC;AAMlG,yDAAyD;AACzD,MAAM,WAAW,oBAAoB;IACjC,+BAA+B;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,sBAAsB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACrD;AAED,iFAAiF;AACjF,MAAM,WAAW,sBAAsB;IACnC,4BAA4B;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,6EAA6E;IAC7E,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,4EAA4E;IAC5E,cAAc,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CACxD;AAED,qFAAqF;AACrF,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG,eAAe,GAAG,gBAAgB,CAAC;AAEpF,iDAAiD;AACjD,MAAM,MAAM,qBAAqB,GAAG;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAEzG;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAClC,OAAO,EAAE,oBAAoB,EAC7B,SAAS,EAAE,sBAAsB,GAAG,IAAI,GAAG,SAAS,GACrD,qBAAqB,CAYvB;AAED,0FAA0F;AAC1F,MAAM,WAAW,sBAAsB;IACnC,+FAA+F;IAC/F,OAAO,EAAE,sBAAsB,CAAC;IAChC,6EAA6E;IAC7E,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACtC,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,QAAQ,EACrB,QAAQ,EAAE,iBAAiB,GAC5B,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CASxC"}
|
|
1
|
+
{"version":3,"file":"sessionAccess.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/sessionAccess.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,iBAAiB,EAAY,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE7E,OAAO,KAAK,EAAE,sBAAsB,EAAwB,MAAM,+BAA+B,CAAC;AAMlG,yDAAyD;AACzD,MAAM,WAAW,oBAAoB;IACjC,+BAA+B;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,sBAAsB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACrD;AAED,iFAAiF;AACjF,MAAM,WAAW,sBAAsB;IACnC,4BAA4B;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,6EAA6E;IAC7E,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,4EAA4E;IAC5E,cAAc,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CACxD;AAED,qFAAqF;AACrF,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG,eAAe,GAAG,gBAAgB,CAAC;AAEpF,iDAAiD;AACjD,MAAM,MAAM,qBAAqB,GAAG;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAEzG;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAClC,OAAO,EAAE,oBAAoB,EAC7B,SAAS,EAAE,sBAAsB,GAAG,IAAI,GAAG,SAAS,GACrD,qBAAqB,CAYvB;AAED,0FAA0F;AAC1F,MAAM,WAAW,sBAAsB;IACnC,+FAA+F;IAC/F,OAAO,EAAE,sBAAsB,CAAC;IAChC,6EAA6E;IAC7E,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACtC,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,QAAQ,EACrB,QAAQ,EAAE,iBAAiB,GAC5B,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CASxC;AAED;;;;GAIG;AACH,wBAAsB,iCAAiC,CACnD,OAAO,EAAE,sBAAsB,EAC/B,WAAW,EAAE,QAAQ,EACrB,QAAQ,EAAE,iBAAiB,GAC5B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAexB"}
|
|
@@ -67,10 +67,14 @@ export async function LoadSessionForAccess(agentSessionId, contextUser, provider
|
|
|
67
67
|
if (!(await session.Load(agentSessionId))) {
|
|
68
68
|
return null;
|
|
69
69
|
}
|
|
70
|
-
return { Session: session, ConversationExternalID: await
|
|
70
|
+
return { Session: session, ConversationExternalID: await LoadSessionConversationExternalID(session, contextUser, provider) };
|
|
71
71
|
}
|
|
72
|
-
/**
|
|
73
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Reads an already-loaded session's conversation `ExternalID` (the anonymous scope id) under `contextUser`;
|
|
74
|
+
* null when there is no conversation or it cannot be read (logged). For callers that loaded the session
|
|
75
|
+
* through another gate and only need the scope half of {@link AuthorizeSessionAccess}'s subject.
|
|
76
|
+
*/
|
|
77
|
+
export async function LoadSessionConversationExternalID(session, contextUser, provider) {
|
|
74
78
|
if (!session.ConversationID) {
|
|
75
79
|
return null;
|
|
76
80
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionAccess.js","sourceRoot":"","sources":["../../src/realtimeSessions/sessionAccess.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAqB,QAAQ,EAAY,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGjE,oFAAoF;AACpF,MAAM,cAAc,GAAG,uBAAuB,CAAC;AAC/C,MAAM,mBAAmB,GAAG,mBAAmB,CAAC;AA8BhD;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAClC,OAA6B,EAC7B,SAAoD;IAEpD,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC;QAC/F,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACnD,CAAC;IACD,MAAM,OAAO,GAAG,SAAS,CAAC,cAAc,EAAE,UAAU,CAAC;IACrD,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,2FAA2F;QAC3F,6EAA6E;QAC7E,OAAO,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC5G,CAAC;IACD,kGAAkG;IAClG,OAAO,OAAO,CAAC,sBAAsB,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;AACzH,CAAC;AAUD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACtC,cAAsB,EACtB,WAAqB,EACrB,QAA2B;IAE3B,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAyB,cAAc,EAAE,WAAW,CAAC,CAAC;IACpG,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,sBAAsB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"sessionAccess.js","sourceRoot":"","sources":["../../src/realtimeSessions/sessionAccess.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,11 @@ import { AppContext } from '../types.js';
|
|
|
9
9
|
*/
|
|
10
10
|
export declare class ArtifactFileResolver extends ResolverBase {
|
|
11
11
|
ArtifactFileDownloadUrl(artifactVersionId: string, context: AppContext): Promise<string>;
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* Load the File (as the caller) and generate a signed URL — after the storage gate: the caller must be able to read
|
|
14
|
+
* the account the file's provider resolves to and every `MJ: Files` row that tracks its object
|
|
15
|
+
* (`FileStorageEngine.ResolveFileObject`), so an artifact cannot sign an object in an account the caller is refused.
|
|
16
|
+
*/
|
|
13
17
|
private buildDownloadUrl;
|
|
14
18
|
}
|
|
15
19
|
//# sourceMappingURL=ArtifactFileResolver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArtifactFileResolver.d.ts","sourceRoot":"","sources":["../../src/resolvers/ArtifactFileResolver.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC;;;;;;GAMG;AACH,qBACa,oBAAqB,SAAQ,YAAY;IAG5C,uBAAuB,CACe,iBAAiB,EAAE,MAAM,EAC1D,OAAO,EAAE,UAAU,GAC3B,OAAO,CAAC,MAAM,CAAC;IA0BlB
|
|
1
|
+
{"version":3,"file":"ArtifactFileResolver.d.ts","sourceRoot":"","sources":["../../src/resolvers/ArtifactFileResolver.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC;;;;;;GAMG;AACH,qBACa,oBAAqB,SAAQ,YAAY;IAG5C,uBAAuB,CACe,iBAAiB,EAAE,MAAM,EAC1D,OAAO,EAAE,UAAU,GAC3B,OAAO,CAAC,MAAM,CAAC;IA0BlB;;;;OAIG;YACW,gBAAgB;CAkBjC"}
|
|
@@ -42,21 +42,23 @@ let ArtifactFileResolver = class ArtifactFileResolver extends ResolverBase {
|
|
|
42
42
|
}
|
|
43
43
|
return this.buildDownloadUrl(artifactVersion.FileID, user, p);
|
|
44
44
|
}
|
|
45
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* Load the File (as the caller) and generate a signed URL — after the storage gate: the caller must be able to read
|
|
47
|
+
* the account the file's provider resolves to and every `MJ: Files` row that tracks its object
|
|
48
|
+
* (`FileStorageEngine.ResolveFileObject`), so an artifact cannot sign an object in an account the caller is refused.
|
|
49
|
+
*/
|
|
46
50
|
async buildDownloadUrl(fileId, user, provider) {
|
|
47
51
|
const fileEntity = await provider.GetEntityObject('MJ: Files', user);
|
|
48
52
|
const fileLoaded = await fileEntity.Load(fileId);
|
|
49
53
|
if (!fileLoaded) {
|
|
50
54
|
throw new Error(`File record ${fileId} not found`);
|
|
51
55
|
}
|
|
52
|
-
//
|
|
53
|
-
await FileStorageEngine.Instance.
|
|
54
|
-
|
|
55
|
-
if (matchingAccounts.length === 0) {
|
|
56
|
+
// Resolve the storage account for this file's provider, gated for the caller (throws on refusal)
|
|
57
|
+
const resolved = await FileStorageEngine.Instance.ResolveFileObject(fileEntity, user, 'Read', provider);
|
|
58
|
+
if (!resolved) {
|
|
56
59
|
throw new Error(`No FileStorageAccount found for ProviderID ${fileEntity.ProviderID}. Cannot generate download URL.`);
|
|
57
60
|
}
|
|
58
|
-
|
|
59
|
-
return driver.CreatePreAuthDownloadUrl(fileEntity.ProviderKey ?? fileEntity.Name);
|
|
61
|
+
return resolved.Driver.CreatePreAuthDownloadUrl(resolved.ObjectKey);
|
|
60
62
|
}
|
|
61
63
|
};
|
|
62
64
|
__decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArtifactFileResolver.js","sourceRoot":"","sources":["../../src/resolvers/ArtifactFileResolver.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;GAMG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,YAAY;IAG5C,AAAN,KAAK,CAAC,uBAAuB,CACe,iBAAyB,EAC1D,OAAmB;QAE1B,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;QACpC,CAAC;QAED,MAAM,CAAC,GAAG,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAElD,4BAA4B;QAC5B,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,eAAe,CAA0B,uBAAuB,EAAE,IAAI,CAAC,CAAC;QACxG,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC7D,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,oBAAoB,iBAAiB,YAAY,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,eAAe,CAAC,WAAW,KAAK,MAAM,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,oBAAoB,iBAAiB,wCAAwC,eAAe,CAAC,WAAW,GAAG,CAAC,CAAC;QACjI,CAAC;QAED,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,oBAAoB,iBAAiB,yBAAyB,CAAC,CAAC;QACpF,CAAC;QAED,OAAO,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"ArtifactFileResolver.js","sourceRoot":"","sources":["../../src/resolvers/ArtifactFileResolver.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;GAMG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,YAAY;IAG5C,AAAN,KAAK,CAAC,uBAAuB,CACe,iBAAyB,EAC1D,OAAmB;QAE1B,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;QACpC,CAAC;QAED,MAAM,CAAC,GAAG,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAElD,4BAA4B;QAC5B,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,eAAe,CAA0B,uBAAuB,EAAE,IAAI,CAAC,CAAC;QACxG,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC7D,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,oBAAoB,iBAAiB,YAAY,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,eAAe,CAAC,WAAW,KAAK,MAAM,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,oBAAoB,iBAAiB,wCAAwC,eAAe,CAAC,WAAW,GAAG,CAAC,CAAC;QACjI,CAAC;QAED,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,oBAAoB,iBAAiB,yBAAyB,CAAC,CAAC;QACpF,CAAC;QAED,OAAO,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,gBAAgB,CAC1B,MAAc,EACd,IAAoD,EACpD,QAA2B;QAE3B,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAe,WAAW,EAAE,IAAI,CAAC,CAAC;QACnF,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjD,IAAI,CAAC,UAAU,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,eAAe,MAAM,YAAY,CAAC,CAAC;QACvD,CAAC;QAED,iGAAiG;QACjG,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,iBAAiB,CAAC,UAAU,EAAE,IAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACzG,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,8CAA8C,UAAU,CAAC,UAAU,iCAAiC,CAAC,CAAC;QAC1H,CAAC;QACD,OAAO,QAAQ,CAAC,MAAM,CAAC,wBAAwB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACxE,CAAC;CACJ,CAAA;AApDS;IADL,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,+FAA+F,EAAE,CAAC;IAEjI,WAAA,GAAG,CAAC,mBAAmB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAA;IACtC,WAAA,GAAG,EAAE,CAAA;;;;mEAyBT;AA9BQ,oBAAoB;IADhC,QAAQ,EAAE;GACE,oBAAoB,CAuDhC"}
|
|
@@ -41,10 +41,14 @@ export declare class ConversationRunEventsOutput {
|
|
|
41
41
|
/**
|
|
42
42
|
* The run's answer, returned only once the run is terminal.
|
|
43
43
|
*
|
|
44
|
-
* Sourced from `AIAgentRun.Result
|
|
45
|
-
*
|
|
46
|
-
* decide a message is finished from {@link IsInFlight} /
|
|
47
|
-
* presence of this field, or it will wait forever on an
|
|
44
|
+
* Sourced from `AIAgentRun.FinalPayload` (`Result` on older rows), then the conversation detail's
|
|
45
|
+
* message, because the run payload is agent-dependent and null on many successful runs. Still
|
|
46
|
+
* nullable: a caller must decide a message is finished from {@link IsInFlight} /
|
|
47
|
+
* {@link DetailStatus}, never from the presence of this field, or it will wait forever on an
|
|
48
|
+
* agent that writes neither.
|
|
49
|
+
*
|
|
50
|
+
* A run that ended without completing (for example `Cancelled`) returns whatever `FinalPayload`
|
|
51
|
+
* it had saved, which can be partial, so a caller should check {@link RunStatus} first.
|
|
48
52
|
*/
|
|
49
53
|
FinalPayload?: string;
|
|
50
54
|
/** `ConversationDetail.Status` — the value the chat UI renders from. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConversationRunEventsResolver.d.ts","sourceRoot":"","sources":["../../src/resolvers/ConversationRunEventsResolver.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAiB9C;;;;;;;;GAQG;AACH,qBACa,oBAAoB;IAC7B,yEAAyE;IAEzE,GAAG,EAAE,MAAM,CAAC;IAGZ,QAAQ,EAAE,MAAM,CAAC;IAGjB,QAAQ,EAAE,MAAM,CAAC;IAGjB,MAAM,EAAE,MAAM,CAAC;IAGf,OAAO,CAAC,EAAE,OAAO,CAAC;IAGlB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,SAAS,EAAE,IAAI,CAAC;IAGhB,WAAW,CAAC,EAAE,IAAI,CAAC;CACtB;AAED,6BAA6B;AAC7B,qBACa,2BAA2B;IAEpC,OAAO,EAAE,OAAO,CAAC;IAGjB,OAAO,EAAE,MAAM,CAAC;IAGhB,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAE/B;;;;OAIG;IAEH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IAEH,UAAU,EAAE,OAAO,CAAC;IAGpB,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB
|
|
1
|
+
{"version":3,"file":"ConversationRunEventsResolver.d.ts","sourceRoot":"","sources":["../../src/resolvers/ConversationRunEventsResolver.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAiB9C;;;;;;;;GAQG;AACH,qBACa,oBAAoB;IAC7B,yEAAyE;IAEzE,GAAG,EAAE,MAAM,CAAC;IAGZ,QAAQ,EAAE,MAAM,CAAC;IAGjB,QAAQ,EAAE,MAAM,CAAC;IAGjB,MAAM,EAAE,MAAM,CAAC;IAGf,OAAO,CAAC,EAAE,OAAO,CAAC;IAGlB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,SAAS,EAAE,IAAI,CAAC;IAGhB,WAAW,CAAC,EAAE,IAAI,CAAC;CACtB;AAED,6BAA6B;AAC7B,qBACa,2BAA2B;IAEpC,OAAO,EAAE,OAAO,CAAC;IAGjB,OAAO,EAAE,MAAM,CAAC;IAGhB,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAE/B;;;;OAIG;IAEH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IAEH,UAAU,EAAE,OAAO,CAAC;IAGpB,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;;;;;OAWG;IAEH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,wEAAwE;IAExE,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAkBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBACa,6BAA6B;IAEhC,sBAAsB,CACmB,oBAAoB,EAAE,MAAM,EAChE,GAAG,EAAE,UAAU,EAC2B,QAAQ,CAAC,EAAE,MAAM,GACnE,OAAO,CAAC,2BAA2B,CAAC;IAoEvC,4FAA4F;YAC9E,UAAU;IAmBxB;;;OAGG;YACW,aAAa;IAqB3B,oFAAoF;YACtE,SAAS;IAsBvB,oFAAoF;IACpF,OAAO,CAAC,OAAO;IAaf,8FAA8F;IAC9F,OAAO,CAAC,MAAM;CAGjB"}
|
|
@@ -14,7 +14,7 @@ import { Arg, Ctx, Field, Int, ObjectType, Query, Resolver } from 'type-graphql'
|
|
|
14
14
|
import { RunView } from '@memberjunction/core';
|
|
15
15
|
import { EscapeSQLString } from '@memberjunction/global';
|
|
16
16
|
import { GetReadOnlyProvider } from '../util.js';
|
|
17
|
-
const RUN_FIELDS = ['ID', 'Status', 'Result'];
|
|
17
|
+
const RUN_FIELDS = ['ID', 'Status', 'FinalPayload', 'Result'];
|
|
18
18
|
const STEP_FIELDS = [
|
|
19
19
|
'StepNumber', 'StepType', 'StepName', 'Status', 'Success', 'ErrorMessage', 'StartedAt', 'CompletedAt',
|
|
20
20
|
];
|
|
@@ -193,11 +193,11 @@ let ConversationRunEventsResolver = class ConversationRunEventsResolver {
|
|
|
193
193
|
// Only meaningful once terminal; sending it mid-run would hand the client a
|
|
194
194
|
// partial payload it could mistake for the final answer.
|
|
195
195
|
//
|
|
196
|
-
// `AIAgentRun.Result` is agent-dependent — it is
|
|
197
|
-
// genuinely successful runs — so the conversation detail's
|
|
198
|
-
// fallback. That is the text the chat renders, so it is the
|
|
199
|
-
// waiting on this field actually wants.
|
|
200
|
-
FinalPayload: isInFlight ? undefined : (run.Result ?? detail.Message ?? undefined),
|
|
196
|
+
// `AIAgentRun.FinalPayload` (`Result` on older rows) is agent-dependent — it is
|
|
197
|
+
// null on a large share of genuinely successful runs — so the conversation detail's
|
|
198
|
+
// own message is the fallback. That is the text the chat renders, so it is the
|
|
199
|
+
// answer a caller waiting on this field actually wants.
|
|
200
|
+
FinalPayload: isInFlight ? undefined : (run.FinalPayload ?? run.Result ?? detail.Message ?? undefined),
|
|
201
201
|
DetailStatus: detail.Status ?? undefined,
|
|
202
202
|
};
|
|
203
203
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConversationRunEventsResolver.js","sourceRoot":"","sources":["../../src/resolvers/ConversationRunEventsResolver.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAIzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAWjD,MAAM,UAAU,GAAyB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"ConversationRunEventsResolver.js","sourceRoot":"","sources":["../../src/resolvers/ConversationRunEventsResolver.ts"],"names":[],"mappings":"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"}
|