nolo-cli 0.1.30 → 0.1.31

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.
Files changed (308) hide show
  1. package/agent-runtime/agentRecordConfig.ts +0 -2
  2. package/agent-runtime/hostAdapter.ts +0 -1
  3. package/agent-runtime/hostRuntimeCapabilities.ts +7 -0
  4. package/agent-runtime/hostRuntimeConfig.ts +86 -0
  5. package/agent-runtime/index.ts +13 -0
  6. package/agent-runtime/localToolPolicy.ts +13 -6
  7. package/agent-runtime/localWorkspaceTools.ts +333 -30
  8. package/agent-runtime/platformChatProvider.ts +4 -1
  9. package/agent-runtime/runtimeToolPolicy.ts +32 -47
  10. package/agent-runtime/shellCommandPolicy.ts +117 -0
  11. package/agent-runtime/toolGate.ts +38 -0
  12. package/agentRecordCommands.ts +1 -1
  13. package/agentRecordHelpers.ts +35 -20
  14. package/agentRunParsing.ts +18 -5
  15. package/agentRuntimeLocal.ts +10 -0
  16. package/ai/agent/agentRunDialogLineage.ts +56 -0
  17. package/ai/agent/agentSlice.ts +45 -10
  18. package/ai/agent/avatarUtils.ts +1 -1
  19. package/ai/agent/buildSystemPrompt.ts +1 -2
  20. package/ai/agent/cliExecutor.ts +330 -19
  21. package/ai/agent/createAgentSchema.ts +22 -0
  22. package/ai/agent/hooks/fetchPublicAgents.ts +14 -39
  23. package/ai/agent/hooks/usePublicAgents.ts +90 -192
  24. package/ai/agent/publicAgentCatalog.ts +359 -0
  25. package/ai/agent/publicAgentIdentity.ts +76 -0
  26. package/ai/agent/server/fetchPublicAgents.ts +21 -46
  27. package/ai/agent/serverOrigin.ts +7 -0
  28. package/ai/agent/streamAgentChatTurn.ts +23 -21
  29. package/ai/agent/streamAgentChatTurnUtils.ts +292 -6
  30. package/ai/agent/types.ts +2 -0
  31. package/ai/agent/web/agentDisplayUtils.ts +171 -0
  32. package/ai/agent/web/useAgentModelAvatarComponent.ts +32 -0
  33. package/ai/ai.locale.ts +8 -0
  34. package/ai/chat/sendOpenAICompletionsRequest.native.ts +15 -0
  35. package/ai/chat/sendOpenAICompletionsRequest.ts +93 -1
  36. package/ai/chat/sendOpenAIResponseRequest.ts +86 -9
  37. package/ai/chat/updateTotalUsage.ts +7 -0
  38. package/ai/llm/deepinfra.ts +30 -15
  39. package/ai/llm/mistral.ts +3 -4
  40. package/ai/llm/providers.ts +2 -0
  41. package/ai/llm/types.ts +15 -0
  42. package/ai/memory/capture.ts +3 -3
  43. package/ai/memory/consolidate.ts +2 -2
  44. package/ai/memory/delete.ts +4 -3
  45. package/ai/memory/query.ts +3 -3
  46. package/ai/memory/remember.ts +2 -2
  47. package/ai/memory/store.ts +3 -3
  48. package/ai/memory/storeShared.ts +3 -2
  49. package/ai/policy/commercialMultiplier.ts +16 -0
  50. package/ai/token/billingAdminAuditEvent.ts +68 -0
  51. package/ai/token/billingAdminAuditEventWriter.ts +41 -0
  52. package/ai/token/billingAnomaly.ts +90 -0
  53. package/ai/token/billingAnomalyLifecycle.ts +54 -0
  54. package/ai/token/billingAnomalyLifecycleWriter.ts +44 -0
  55. package/ai/token/billingAnomalyWriter.ts +41 -0
  56. package/ai/token/calculatePrice.ts +3 -2
  57. package/ai/token/deepinfraReconciliation.ts +153 -0
  58. package/ai/token/deepinfraRequestIdQuery.ts +92 -0
  59. package/ai/token/externalToolCost.ts +54 -41
  60. package/ai/token/missingUsageEstimate.ts +12 -3
  61. package/ai/token/normalizeUsage.ts +45 -5
  62. package/ai/token/openaiReconciliation.ts +188 -0
  63. package/ai/token/providerBillableEvent.ts +84 -0
  64. package/ai/token/providerBillableEventWriter.ts +36 -0
  65. package/ai/token/providerBillingAnomalyDrilldown.ts +308 -0
  66. package/ai/token/providerBillingDrilldown.ts +361 -0
  67. package/ai/token/providerBillingHealthReport.ts +366 -0
  68. package/ai/token/providerCall.ts +144 -0
  69. package/ai/token/providerCallSweeper.ts +168 -0
  70. package/ai/token/providerCallWriter.ts +33 -0
  71. package/ai/token/providerCredential.ts +89 -0
  72. package/ai/token/providerCredentialAnomaly.ts +154 -0
  73. package/ai/token/providerCredentialLifecycle.ts +59 -0
  74. package/ai/token/providerCredentialLifecycleWriter.ts +44 -0
  75. package/ai/token/providerCredentialRegistry.ts +83 -0
  76. package/ai/token/providerCredentialRegistryCommand.ts +97 -0
  77. package/ai/token/providerCredentialRegistryList.ts +124 -0
  78. package/ai/token/providerCredentialRegistryResolver.ts +150 -0
  79. package/ai/token/providerCredentialRegistryWriter.ts +41 -0
  80. package/ai/token/providerCredentialRotationCommand.ts +102 -0
  81. package/ai/token/providerCredentialRuntime.ts +56 -0
  82. package/ai/token/providerDispatchIntent.ts +67 -0
  83. package/ai/token/providerDispatchIntentWriter.ts +36 -0
  84. package/ai/token/providerGateway.ts +260 -0
  85. package/ai/token/providerReconciliation.ts +148 -0
  86. package/ai/token/providerReconciliationLocal.ts +97 -0
  87. package/ai/token/providerReconciliationRunner.ts +165 -0
  88. package/ai/token/providerReconciliationWriter.ts +41 -0
  89. package/ai/token/ratingResult.ts +202 -0
  90. package/ai/token/ratingResultWriter.ts +33 -0
  91. package/ai/token/serverDialogProjection.ts +5 -3
  92. package/ai/token/serverTokenWriter.ts +11 -3
  93. package/ai/token/types.ts +10 -0
  94. package/ai/tools/agent/callAgentTool.ts +3 -4
  95. package/ai/tools/agent/presets/appBuilderPreset.ts +5 -7
  96. package/ai/tools/agent/runStreamingAgentTool.ts +1 -2
  97. package/ai/tools/agent/streamParallelAgentsTool.ts +2 -3
  98. package/ai/tools/readXPostTool.ts +1 -5
  99. package/app/admin/adminPages.ts +9 -0
  100. package/app/i18n/i18n.config.ts +5 -0
  101. package/app/i18n/translations/pricing.locale.ts +397 -0
  102. package/app/utils/desktopAgentRuntimeStatusClient.ts +5 -4
  103. package/app/utils/desktopAgentRuntimeTurnClient.ts +4 -1
  104. package/app/utils/imageUtils.ts +64 -34
  105. package/auth/adminPermissions.ts +18 -0
  106. package/auth/authSlice.ts +26 -12
  107. package/auth/hooks/useFetchUsers.ts +3 -0
  108. package/auth/routes.ts +46 -0
  109. package/auth/server/accessActivity.ts +4 -3
  110. package/auth/server/adminPermissions.ts +43 -0
  111. package/auth/server/adminUsageReport.ts +375 -0
  112. package/auth/server/billingAnomalies.ts +235 -0
  113. package/auth/server/billingUsageReport.ts +41 -2
  114. package/auth/server/creatorEarningCreditConversion.ts +10 -2
  115. package/auth/server/deduct.ts +14 -7
  116. package/auth/server/delete.ts +10 -2
  117. package/auth/server/disable.ts +4 -3
  118. package/auth/server/emailAutomation.ts +7 -5
  119. package/auth/server/emailDbConfig.ts +4 -2
  120. package/auth/server/emailDelivery.ts +24 -20
  121. package/auth/server/emailDeliveryGuards.ts +10 -7
  122. package/auth/server/emailPreferences.ts +6 -4
  123. package/auth/server/emailReport.ts +6 -4
  124. package/auth/server/emailRuntimeConfig.ts +3 -3
  125. package/auth/server/emailScenarioNotifications.ts +9 -8
  126. package/auth/server/enable.ts +4 -3
  127. package/auth/server/getRechargeHistory.ts +3 -2
  128. package/auth/server/getUser.ts +3 -2
  129. package/auth/server/gptProAccess.ts +44 -0
  130. package/auth/server/inviteReward.ts +10 -7
  131. package/auth/server/listusers.ts +6 -4
  132. package/auth/server/login.ts +2 -2
  133. package/auth/server/productEntitlements.ts +7 -4
  134. package/auth/server/productPurchase.ts +10 -2
  135. package/auth/server/providerBillingDrilldown.ts +47 -0
  136. package/auth/server/providerBillingHealth.ts +71 -0
  137. package/auth/server/providerCredentials.ts +136 -0
  138. package/auth/server/recharge.ts +14 -8
  139. package/auth/server/revokeSessions.ts +4 -3
  140. package/auth/server/route.ts +77 -0
  141. package/auth/server/sendEmail.ts +5 -4
  142. package/auth/server/signup.ts +10 -3
  143. package/auth/server/token.ts +53 -55
  144. package/auth/server/tokenUsageBilling.ts +18 -7
  145. package/auth/server/usageManagementAccess.ts +43 -0
  146. package/auth/server/usageReport.ts +59 -0
  147. package/auth/types.ts +12 -0
  148. package/auth/utils.ts +24 -22
  149. package/authCommands.ts +36 -2
  150. package/buildPublish.ts +3 -1
  151. package/buildPublishArtifactAssembly.ts +62 -1
  152. package/buildPublishImportAnalysis.ts +21 -16
  153. package/chat/dialog/dialogLaunchScope.ts +32 -0
  154. package/chat/dialog/objectAssistantRegistry.ts +2 -2
  155. package/chat/dialog/useCreateDialog.ts +1 -1
  156. package/chat/hooks/useChatInput.ts +41 -10
  157. package/chat/messages/messageSlice.ts +5 -1
  158. package/chat/messages/pendingAttachmentParts.ts +28 -2
  159. package/chat/messages/sendFirstMessage.ts +76 -79
  160. package/chat/messages/types.ts +9 -0
  161. package/chat/messages/web/streamingMarkdownModel.ts +41 -0
  162. package/chat/messages/web/useStreamingReveal.ts +91 -0
  163. package/chat/web/messageInputAgentUi.ts +94 -6
  164. package/cliEnvHelpers.ts +8 -0
  165. package/cliRuntimeDoctorReport.ts +193 -0
  166. package/client/agentConfigResolver.test.ts +0 -2
  167. package/client/agentRun.test.ts +171 -10
  168. package/client/agentRun.ts +44 -637
  169. package/client/agentRunInput.ts +10 -0
  170. package/client/agentRunLocalExecutor.ts +179 -0
  171. package/client/agentRunServerTransport.ts +394 -0
  172. package/client/agentRunTaskRunRecorder.ts +176 -0
  173. package/client/localRuntimeAdapter.test.ts +236 -9
  174. package/client/localRuntimeAdapter.ts +221 -23
  175. package/client/localToolPolicy.test.ts +28 -4
  176. package/connector-experimental/daemonLauncher.ts +38 -4
  177. package/connectorRunArtifact.ts +34 -10
  178. package/connectorWebSocketTarget.ts +9 -5
  179. package/core/builtinAgents.ts +155 -11
  180. package/create/space/contentLabels.ts +1 -1
  181. package/create/space/contentTypeMeta.ts +3 -2
  182. package/create/space/sidebarVisibleTypes.ts +27 -0
  183. package/create/space/space.locale.ts +76 -4
  184. package/database/actions/agentReadResolution.ts +2 -8
  185. package/database/actions/read.ts +11 -9
  186. package/database/actions/readAndWait.ts +10 -5
  187. package/database/server/agentDelegation.ts +3 -2
  188. package/database/server/authorityStoreConformance.ts +209 -0
  189. package/database/server/authorityStoreTypes.ts +31 -0
  190. package/database/server/coreDataProxy.ts +1 -1
  191. package/database/server/dataHandlers.ts +13 -5
  192. package/database/server/db.ts +15 -34
  193. package/database/server/delete.ts +88 -71
  194. package/database/server/emailRepository.ts +11 -9
  195. package/database/server/fileService.ts +2 -1
  196. package/database/server/legacyServerDb.ts +58 -0
  197. package/database/server/levelAuthorityStore.ts +75 -0
  198. package/database/server/memoryAuthorityStore.ts +133 -0
  199. package/database/server/patch.ts +13 -12
  200. package/database/server/query.ts +3 -2
  201. package/database/server/read.ts +33 -30
  202. package/database/server/resourceAccess.ts +7 -5
  203. package/database/server/serverStoreFactory.ts +124 -0
  204. package/database/server/spaceMemberAuthority.ts +3 -2
  205. package/database/server/storeBatchCompat.ts +37 -0
  206. package/database/server/testAuthorityStore.ts +76 -0
  207. package/database/server/write.ts +29 -27
  208. package/integrations/anthropic/anthropicModels.ts +12 -12
  209. package/integrations/deepseek/models.ts +67 -67
  210. package/integrations/google/models.ts +111 -53
  211. package/integrations/openai/models.ts +22 -22
  212. package/integrations/xai/models.ts +1 -1
  213. package/localRuntimeDb.ts +39 -2
  214. package/machineCommandPrompts.ts +2 -0
  215. package/machineCommands.ts +193 -63
  216. package/machineWsRunDispatch.ts +80 -15
  217. package/machineWsSession.ts +39 -2
  218. package/noloReadBridgePrompt.ts +16 -0
  219. package/package.json +99 -6
  220. package/render/layout/mainLayoutViewMode.ts +25 -0
  221. package/render/page/server/createPage.ts +3 -1
  222. package/render/page/server/handleCreatePage.ts +2 -11
  223. package/runtimeDoctorCommands.ts +15 -66
  224. package/server/api/methods.ts +34 -12
  225. package/server/api/tableHandlers.ts +6 -3
  226. package/server/authenticateToken.ts +47 -2
  227. package/server/billingLedgerRoutes.ts +15 -0
  228. package/server/buildManifest.ts +54 -0
  229. package/server/coreReadiness.ts +34 -25
  230. package/server/coreRuntime.ts +15 -10
  231. package/server/handlers/activityStatsHandler.ts +5 -2
  232. package/server/handlers/agentEmailRegistrationE2EHandler.ts +25 -23
  233. package/server/handlers/agentRun/agentLookup.ts +1 -7
  234. package/server/handlers/agentRun/autonomousRuntime.ts +11 -10
  235. package/server/handlers/agentRun/builtinAgents.ts +12 -88
  236. package/server/handlers/agentRun/continueDialogContext.ts +15 -3
  237. package/server/handlers/agentRun/{inheritedDialogPrompt.ts → conversationReference.ts} +3 -3
  238. package/server/handlers/agentRun/dialogLookup.ts +4 -3
  239. package/server/handlers/agentRun/index.ts +864 -404
  240. package/server/handlers/agentRun/localRuntimeBootstrap.ts +17 -1
  241. package/server/handlers/agentRun/loop.ts +920 -508
  242. package/server/handlers/agentRun/machineConnector.ts +56 -8
  243. package/server/handlers/agentRun/machineRunAudit.ts +3 -2
  244. package/server/handlers/agentRun/modelUsageToolHandlers.ts +13 -10
  245. package/server/handlers/agentRun/requestContext.ts +12 -8
  246. package/server/handlers/agentRun/runtimeExecutionContext.ts +15 -3
  247. package/server/handlers/agentRun/runtimePreparation.ts +26 -24
  248. package/server/handlers/agentRun/runtimeRouting.ts +25 -40
  249. package/server/handlers/agentRun/runtimeSystemMessages.ts +65 -0
  250. package/server/handlers/agentRun/saveDialog.ts +97 -87
  251. package/server/handlers/agentRun/taskRunToolHandler.ts +9 -7
  252. package/server/handlers/agentRun/toolExecutor.ts +42 -78
  253. package/server/handlers/agentRun/types.ts +2 -1
  254. package/server/handlers/appDeployStatusStore.ts +17 -10
  255. package/server/handlers/appDomainHandler.ts +21 -15
  256. package/server/handlers/appLegacyInfraCleanup.ts +5 -2
  257. package/server/handlers/appSandboxHandler.ts +29 -8
  258. package/server/handlers/appSpaceAccess.ts +15 -8
  259. package/server/handlers/chatHandler.ts +22 -2
  260. package/server/handlers/chatUpstreamRetry.ts +225 -2
  261. package/server/handlers/connector/connectorConnectionRegistry.ts +55 -7
  262. package/server/handlers/connector/connectorWebSocket.ts +14 -10
  263. package/server/handlers/desktopAgentRuntimeAdapter.ts +4 -4
  264. package/server/handlers/desktopAgentRuntimeHostCapabilities.ts +25 -0
  265. package/server/handlers/desktopAgentRuntimeReadiness.ts +62 -0
  266. package/server/handlers/desktopAgentRuntimeStatusHandler.ts +38 -30
  267. package/server/handlers/desktopAgentRuntimeTurnHandler.ts +7 -3
  268. package/server/handlers/desktopAgentRuntimeTurnService.ts +39 -45
  269. package/server/handlers/desktopLlamaRuntimeHandler.ts +85 -51
  270. package/server/handlers/desktopUpdaterHandler.ts +132 -24
  271. package/server/handlers/favoriteHandlers.ts +8 -2
  272. package/server/handlers/getDialogBillingHandler.ts +4 -3
  273. package/server/handlers/getTransactionsHandler.ts +5 -2
  274. package/server/handlers/machines/machineBinding.ts +1 -0
  275. package/server/handlers/machines/machineHandlers.ts +0 -14
  276. package/server/handlers/machines/machineInstallAssets.ts +4 -2
  277. package/server/handlers/notificationEmitter.ts +5 -3
  278. package/server/handlers/notificationsHandler.ts +5 -2
  279. package/server/handlers/providerCallsRecentHandler.ts +234 -0
  280. package/server/handlers/providerReconciliationRunHandler.ts +180 -0
  281. package/server/handlers/providerRequestIdsHandler.ts +105 -0
  282. package/server/handlers/tableAccess.ts +6 -2
  283. package/server/handlers/tableToolHandlers.ts +28 -14
  284. package/server/handlers/userSecretsHandler.ts +17 -6
  285. package/server/handlers/versionHandler.ts +9 -4
  286. package/server/handlers/versionStore.ts +18 -10
  287. package/server/html/ssrPreload.ts +5 -3
  288. package/server/payments/crypto/cryptoUsdcBasePaymentProvider.ts +11 -8
  289. package/server/payments/crypto/cryptoUsdcBaseScanner.ts +12 -7
  290. package/server/payments/crypto/cryptoUsdtTronPaymentProvider.ts +11 -8
  291. package/server/payments/crypto/cryptoUsdtTronScanner.ts +9 -7
  292. package/server/payments/waffo/waffoPaymentProvider.ts +12 -9
  293. package/server/runtimeRole.ts +15 -0
  294. package/server/scheduler/scheduledTaskRuntime.ts +4 -2
  295. package/server/scheduler/schedulerService.ts +2 -2
  296. package/server/taskRunBridgeRoutes.ts +8 -5
  297. package/share/server/fetchCommunityShares.ts +1 -1
  298. package/share/server/helpers.ts +19 -17
  299. package/share/server/importShare.ts +9 -13
  300. package/share/server/listCommunityShares.ts +4 -4
  301. package/share/server/purchaseDoc.ts +8 -16
  302. package/share/server/readCommunityShareCover.ts +3 -2
  303. package/share/server/readSharedTable.ts +14 -13
  304. package/share/server/tableReplication.ts +42 -39
  305. package/spaceAttachCommands.ts +135 -0
  306. package/spaceInternalCommandEntries.ts +2 -0
  307. package/ai/agent/runtimeServerBase.ts +0 -37
  308. package/server/handlers/desktopAgentRuntimeHostFacts.ts +0 -40
@@ -0,0 +1,150 @@
1
+ import type { ProviderCredentialIdentity } from "./providerCredential";
2
+ import type { ProviderCredentialLifecycleEvent } from "./providerCredentialLifecycle";
3
+ import {
4
+ buildProviderCredentialRegistryKey,
5
+ type ProviderCredentialRegistryRecord,
6
+ } from "./providerCredentialRegistry";
7
+
8
+ export type ProviderCredentialRegistryReadStore = {
9
+ get(key: string): Promise<unknown>;
10
+ iterator?(options?: { gte?: string; lte?: string }): AsyncIterable<[string, unknown]>;
11
+ };
12
+
13
+ const LIFECYCLE_PREFIX = "provider-credential-lifecycle-";
14
+
15
+ const isMissingRecordError = (error: unknown) => {
16
+ if (!error || typeof error !== "object") return false;
17
+ const code = (error as { code?: unknown }).code;
18
+ const message = (error as { message?: unknown }).message;
19
+ return (
20
+ code === "LEVEL_NOT_FOUND" ||
21
+ code === "NOT_FOUND" ||
22
+ message === "NotFound"
23
+ );
24
+ };
25
+
26
+ function isRegistryRecord(value: unknown): value is ProviderCredentialRegistryRecord {
27
+ if (!value || typeof value !== "object") return false;
28
+ const record = value as Partial<ProviderCredentialRegistryRecord>;
29
+ return (
30
+ record.schemaVersion === 1 &&
31
+ record.recordType === "provider_credential" &&
32
+ typeof record.credentialId === "string" &&
33
+ typeof record.provider === "string" &&
34
+ typeof record.providerAccountKey === "string" &&
35
+ typeof record.credentialFingerprint === "string" &&
36
+ typeof record.apiKeySource === "string" &&
37
+ typeof record.status === "string"
38
+ );
39
+ }
40
+
41
+ function isLifecycleEvent(value: unknown): value is ProviderCredentialLifecycleEvent {
42
+ if (!value || typeof value !== "object") return false;
43
+ const event = value as Partial<ProviderCredentialLifecycleEvent>;
44
+ return (
45
+ event.schemaVersion === 1 &&
46
+ event.recordType === "provider_credential_lifecycle_event" &&
47
+ typeof event.credentialId === "string" &&
48
+ typeof event.eventId === "string" &&
49
+ typeof event.status === "string" &&
50
+ typeof event.effectiveAt === "string" &&
51
+ typeof event.createdAt === "string"
52
+ );
53
+ }
54
+
55
+ function isEffective(record: ProviderCredentialRegistryRecord, at: string) {
56
+ const atMs = Date.parse(at);
57
+ const fromMs = Date.parse(record.effectiveFrom);
58
+ const toMs = record.effectiveTo ? Date.parse(record.effectiveTo) : undefined;
59
+ if (!Number.isFinite(atMs) || !Number.isFinite(fromMs)) return false;
60
+ if (atMs < fromMs) return false;
61
+ return typeof toMs !== "number" || !Number.isFinite(toMs) || atMs < toMs;
62
+ }
63
+
64
+ async function findLatestEffectiveLifecycleEvent({
65
+ store,
66
+ credentialId,
67
+ at,
68
+ }: {
69
+ store: ProviderCredentialRegistryReadStore;
70
+ credentialId: string;
71
+ at: string;
72
+ }) {
73
+ if (!store.iterator) return undefined;
74
+ const atMs = Date.parse(at);
75
+ if (!Number.isFinite(atMs)) return undefined;
76
+ const prefix = `${LIFECYCLE_PREFIX}${credentialId}-event-`;
77
+ let latest: ProviderCredentialLifecycleEvent | undefined;
78
+ for await (const [, value] of store.iterator({
79
+ gte: prefix,
80
+ lte: `${prefix}\uffff`,
81
+ })) {
82
+ if (!isLifecycleEvent(value)) continue;
83
+ if (value.credentialId !== credentialId) continue;
84
+ const effectiveMs = Date.parse(value.effectiveAt);
85
+ if (!Number.isFinite(effectiveMs) || effectiveMs > atMs) continue;
86
+ if (!latest) {
87
+ latest = value;
88
+ continue;
89
+ }
90
+ const latestMs = Date.parse(latest.effectiveAt);
91
+ if (
92
+ latestMs < effectiveMs ||
93
+ (latest.effectiveAt === value.effectiveAt && latest.createdAt < value.createdAt)
94
+ ) {
95
+ latest = value;
96
+ }
97
+ }
98
+ return latest;
99
+ }
100
+
101
+ export async function resolveProviderCredentialIdentity({
102
+ store,
103
+ provider,
104
+ identity,
105
+ at = new Date().toISOString(),
106
+ }: {
107
+ store?: ProviderCredentialRegistryReadStore;
108
+ provider: string;
109
+ identity?: ProviderCredentialIdentity;
110
+ at?: string;
111
+ }): Promise<ProviderCredentialIdentity | undefined> {
112
+ if (!identity || !store) return identity;
113
+ let value: unknown;
114
+ try {
115
+ value = await store.get(buildProviderCredentialRegistryKey(identity.credentialId));
116
+ } catch (error) {
117
+ if (isMissingRecordError(error)) return identity;
118
+ throw error;
119
+ }
120
+ if (!isRegistryRecord(value)) return identity;
121
+ const record = value;
122
+ if (record.provider !== provider.trim().toLowerCase()) return identity;
123
+ if (record.credentialFingerprint !== identity.credentialFingerprint) return identity;
124
+ if (record.status === "revoked") return identity;
125
+ if (!isEffective(record, at)) return identity;
126
+ const lifecycle = await findLatestEffectiveLifecycleEvent({
127
+ store,
128
+ credentialId: record.credentialId,
129
+ at,
130
+ });
131
+ const registryStatus = lifecycle?.status ?? record.status;
132
+ return {
133
+ ...identity,
134
+ providerAccountKey: record.providerAccountKey,
135
+ ...(record.providerAccountAlias
136
+ ? { providerAccountAlias: record.providerAccountAlias }
137
+ : {}),
138
+ ...(record.environment ? { environment: record.environment } : {}),
139
+ ...(record.officialBillingAccountId
140
+ ? { officialBillingAccountId: record.officialBillingAccountId }
141
+ : {}),
142
+ registryStatus,
143
+ registryEffectiveFrom: record.effectiveFrom,
144
+ ...(registryStatus === "revoked" && lifecycle
145
+ ? { registryEffectiveTo: lifecycle.effectiveAt }
146
+ : record.effectiveTo
147
+ ? { registryEffectiveTo: record.effectiveTo }
148
+ : {}),
149
+ };
150
+ }
@@ -0,0 +1,41 @@
1
+ import {
2
+ buildProviderCredentialRegistryKey,
3
+ type ProviderCredentialRegistryRecord,
4
+ } from "./providerCredentialRegistry";
5
+
6
+ export type ProviderCredentialRegistryStore = {
7
+ get(key: string): Promise<unknown>;
8
+ put(key: string, value: unknown): Promise<void>;
9
+ };
10
+
11
+ const isMissingRecordError = (error: unknown) => {
12
+ if (!error || typeof error !== "object") return false;
13
+ const code = (error as { code?: unknown }).code;
14
+ const message = (error as { message?: unknown }).message;
15
+ return (
16
+ code === "LEVEL_NOT_FOUND" ||
17
+ code === "NOT_FOUND" ||
18
+ message === "NotFound"
19
+ );
20
+ };
21
+
22
+ export async function writeProviderCredentialRegistryRecord({
23
+ store,
24
+ record,
25
+ }: {
26
+ store: ProviderCredentialRegistryStore;
27
+ record: ProviderCredentialRegistryRecord;
28
+ }): Promise<{ key: string }> {
29
+ const key = buildProviderCredentialRegistryKey(record.credentialId);
30
+ let existing: unknown;
31
+ try {
32
+ existing = await store.get(key);
33
+ } catch (error) {
34
+ if (!isMissingRecordError(error)) throw error;
35
+ }
36
+ if (existing) {
37
+ throw new Error(`provider credential registry record already exists: ${key}`);
38
+ }
39
+ await store.put(key, record);
40
+ return { key };
41
+ }
@@ -0,0 +1,102 @@
1
+ import {
2
+ createProviderCredentialLifecycleEvent,
3
+ type ProviderCredentialLifecycleEvent,
4
+ } from "./providerCredentialLifecycle";
5
+ import {
6
+ buildProviderCredentialRegistryRegistration,
7
+ type ProviderCredentialRegistryPublicSummary,
8
+ } from "./providerCredentialRegistryCommand";
9
+ import type {
10
+ ProviderCredentialRegistryRecord,
11
+ ProviderCredentialStatus,
12
+ } from "./providerCredentialRegistry";
13
+ import type { ProviderApiKeySource } from "./providerCredential";
14
+ import type { RuntimeCredentialEnv } from "./providerCredentialRuntime";
15
+
16
+ export type ProviderCredentialRotationPublicSummary = {
17
+ oldCredential: {
18
+ credentialId: string;
19
+ provider: string;
20
+ providerAccountKey: string;
21
+ providerAccountAlias?: string;
22
+ status: ProviderCredentialStatus;
23
+ effectiveAt: string;
24
+ };
25
+ newCredential: ProviderCredentialRegistryPublicSummary;
26
+ };
27
+
28
+ export function buildProviderCredentialRotationPlan({
29
+ oldRecord,
30
+ newApiKey,
31
+ newApiKeySource,
32
+ env = process.env,
33
+ oldStatus,
34
+ effectiveAt,
35
+ createdAt,
36
+ eventId,
37
+ actorId,
38
+ reason,
39
+ providerAccountAlias,
40
+ officialBillingAccountId,
41
+ note,
42
+ }: {
43
+ oldRecord: ProviderCredentialRegistryRecord;
44
+ newApiKey?: string | null;
45
+ newApiKeySource: ProviderApiKeySource;
46
+ env?: RuntimeCredentialEnv;
47
+ oldStatus: Extract<ProviderCredentialStatus, "rotating" | "revoked">;
48
+ effectiveAt: string;
49
+ createdAt: string;
50
+ eventId: string;
51
+ actorId?: string | null;
52
+ reason?: string | null;
53
+ providerAccountAlias?: string | null;
54
+ officialBillingAccountId?: string | null;
55
+ note?: string | null;
56
+ }): {
57
+ oldLifecycleEvent: ProviderCredentialLifecycleEvent;
58
+ newRegistration: ReturnType<typeof buildProviderCredentialRegistryRegistration>;
59
+ publicSummary: ProviderCredentialRotationPublicSummary;
60
+ } {
61
+ const oldLifecycleEvent = createProviderCredentialLifecycleEvent({
62
+ credentialId: oldRecord.credentialId,
63
+ eventId,
64
+ status: oldStatus,
65
+ effectiveAt,
66
+ createdAt,
67
+ reason,
68
+ actorId,
69
+ });
70
+ const newRegistration = buildProviderCredentialRegistryRegistration({
71
+ provider: oldRecord.provider,
72
+ apiKey: newApiKey,
73
+ apiKeySource: newApiKeySource,
74
+ env,
75
+ providerAccountAlias:
76
+ providerAccountAlias ?? oldRecord.providerAccountAlias ?? undefined,
77
+ officialBillingAccountId:
78
+ officialBillingAccountId ?? oldRecord.officialBillingAccountId ?? undefined,
79
+ effectiveFrom: effectiveAt,
80
+ createdAt,
81
+ status: "active",
82
+ note,
83
+ });
84
+ if (newRegistration.record.credentialId === oldRecord.credentialId) {
85
+ throw new Error("new credential must differ from old credential");
86
+ }
87
+ return {
88
+ oldLifecycleEvent,
89
+ newRegistration,
90
+ publicSummary: {
91
+ oldCredential: {
92
+ credentialId: oldRecord.credentialId,
93
+ provider: oldRecord.provider,
94
+ providerAccountKey: oldRecord.providerAccountKey,
95
+ providerAccountAlias: oldRecord.providerAccountAlias,
96
+ status: oldLifecycleEvent.status,
97
+ effectiveAt: oldLifecycleEvent.effectiveAt,
98
+ },
99
+ newCredential: newRegistration.publicSummary,
100
+ },
101
+ };
102
+ }
@@ -0,0 +1,56 @@
1
+ import {
2
+ createProviderCredentialIdentity,
3
+ type ProviderApiKeySource,
4
+ type ProviderCredentialIdentity,
5
+ } from "./providerCredential";
6
+ import {
7
+ resolveProviderCredentialIdentity,
8
+ type ProviderCredentialRegistryReadStore,
9
+ } from "./providerCredentialRegistryResolver";
10
+
11
+ export type RuntimeCredentialEnv = Record<string, string | undefined>;
12
+
13
+ const providerAccountAlias = (provider: string, env: RuntimeCredentialEnv) => {
14
+ const normalized = provider.trim().toUpperCase().replace(/[^A-Z0-9]+/g, "_");
15
+ return (
16
+ env[`NOLO_${normalized}_ACCOUNT_ALIAS`]?.trim() ||
17
+ env[`${normalized}_ACCOUNT_ALIAS`]?.trim() ||
18
+ undefined
19
+ );
20
+ };
21
+
22
+ const credentialEnvironment = (env: RuntimeCredentialEnv) =>
23
+ env.NOLO_DEPLOY_ENV?.trim() ||
24
+ env.NOLO_ENV?.trim() ||
25
+ env.NODE_ENV?.trim() ||
26
+ undefined;
27
+
28
+ export async function resolveRuntimeProviderCredential({
29
+ provider,
30
+ apiKey,
31
+ apiKeySource,
32
+ env = process.env,
33
+ registryStore,
34
+ at,
35
+ }: {
36
+ provider: string;
37
+ apiKey?: string | null;
38
+ apiKeySource: ProviderApiKeySource;
39
+ env?: RuntimeCredentialEnv;
40
+ registryStore?: ProviderCredentialRegistryReadStore;
41
+ at?: string;
42
+ }): Promise<ProviderCredentialIdentity | undefined> {
43
+ const identity = createProviderCredentialIdentity({
44
+ provider,
45
+ apiKey,
46
+ apiKeySource,
47
+ providerAccountAlias: providerAccountAlias(provider, env),
48
+ environment: credentialEnvironment(env),
49
+ });
50
+ return resolveProviderCredentialIdentity({
51
+ store: registryStore,
52
+ provider,
53
+ identity,
54
+ at,
55
+ });
56
+ }
@@ -0,0 +1,67 @@
1
+ import type { ProviderCredentialIdentity } from "./providerCredential";
2
+
3
+ export type ProviderDispatchIntentStatus = "dispatching";
4
+
5
+ export type ProviderDispatchIntent = {
6
+ providerCallId: string;
7
+ intentId: string;
8
+ userId: string;
9
+ dialogId?: string;
10
+ agentId?: string;
11
+ provider: string;
12
+ model: string;
13
+ endpoint?: string;
14
+ serviceTier?: string;
15
+ credential?: ProviderCredentialIdentity;
16
+ request: {
17
+ url: string;
18
+ method: string;
19
+ bodyHash?: string;
20
+ };
21
+ status: ProviderDispatchIntentStatus;
22
+ createdAt: string;
23
+ };
24
+
25
+ export type CreateProviderDispatchIntentInput = {
26
+ providerCallId: string;
27
+ intentId: string;
28
+ userId: string;
29
+ dialogId?: string;
30
+ agentId?: string;
31
+ provider: string;
32
+ model: string;
33
+ endpoint?: string;
34
+ serviceTier?: string;
35
+ credential?: ProviderCredentialIdentity;
36
+ url: string;
37
+ method: string;
38
+ bodyHash?: string;
39
+ createdAt: string;
40
+ };
41
+
42
+ export const buildProviderDispatchIntentKey = (
43
+ providerCallId: string,
44
+ intentId: string
45
+ ) => `provider-dispatch-intent-${providerCallId}-${intentId}`;
46
+
47
+ export const createProviderDispatchIntent = (
48
+ input: CreateProviderDispatchIntentInput
49
+ ): ProviderDispatchIntent => ({
50
+ providerCallId: input.providerCallId,
51
+ intentId: input.intentId,
52
+ userId: input.userId,
53
+ dialogId: input.dialogId,
54
+ agentId: input.agentId,
55
+ provider: input.provider,
56
+ model: input.model,
57
+ endpoint: input.endpoint,
58
+ serviceTier: input.serviceTier,
59
+ credential: input.credential,
60
+ request: {
61
+ url: input.url,
62
+ method: input.method,
63
+ bodyHash: input.bodyHash,
64
+ },
65
+ status: "dispatching",
66
+ createdAt: input.createdAt,
67
+ });
@@ -0,0 +1,36 @@
1
+ import {
2
+ buildProviderDispatchIntentKey,
3
+ type ProviderDispatchIntent,
4
+ } from "./providerDispatchIntent";
5
+
6
+ export type ProviderDispatchIntentStore = {
7
+ get(key: string): Promise<unknown>;
8
+ put(key: string, value: unknown): Promise<void>;
9
+ };
10
+
11
+ const isMissingRecordError = (error: unknown) => {
12
+ if (!error || typeof error !== "object") return false;
13
+ const code = (error as { code?: unknown }).code;
14
+ return code === "LEVEL_NOT_FOUND" || code === "NOT_FOUND";
15
+ };
16
+
17
+ export async function writeProviderDispatchIntent({
18
+ store,
19
+ intent,
20
+ }: {
21
+ store: ProviderDispatchIntentStore;
22
+ intent: ProviderDispatchIntent;
23
+ }): Promise<{ key: string }> {
24
+ const key = buildProviderDispatchIntentKey(intent.providerCallId, intent.intentId);
25
+ let existing: unknown;
26
+ try {
27
+ existing = await store.get(key);
28
+ } catch (error) {
29
+ if (!isMissingRecordError(error)) throw error;
30
+ }
31
+ if (existing) {
32
+ throw new Error(`provider dispatch intent already exists: ${key}`);
33
+ }
34
+ await store.put(key, intent);
35
+ return { key };
36
+ }