@granular-software/sdk 0.4.51 → 0.4.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-evals.d.mts +2 -2
- package/dist/agent-evals.d.ts +2 -2
- package/dist/agent-evals.js +236 -31
- package/dist/agent-evals.js.map +1 -1
- package/dist/agent-evals.mjs +236 -31
- package/dist/agent-evals.mjs.map +1 -1
- package/dist/cli/index.js +267 -50
- package/dist/{client-djorlOpn.d.mts → client-B2OyGOHE.d.mts} +18 -3
- package/dist/{client-NSH-tpNU.d.ts → client-BMfjRJTs.d.ts} +18 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +236 -31
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +236 -31
- package/dist/index.mjs.map +1 -1
- package/dist/{spend-BA-jZwZ0.d.mts → spend-DpRRCrAr.d.mts} +37 -2
- package/dist/{spend-BA-jZwZ0.d.ts → spend-DpRRCrAr.d.ts} +37 -2
- package/dist/spend.d.mts +1 -1
- package/dist/spend.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { E as Environment, a as EnvironmentSession, G as Granular, O as OntologyHandle, S as Session, W as WSClient } from './client-
|
|
2
|
-
import { E as EndpointMode, T as ToolWithHandler, a as EffectHandlerContext, M as ManifestEffectMetamodelSpec, R as ResolvedEffectBehaviors, S as SessionHeapEntry, b as SessionHeapList, c as SessionHeapSnapshot, P as Prompt, d as SessionTranscriptEntry } from './spend-
|
|
3
|
-
export {
|
|
1
|
+
export { E as Environment, a as EnvironmentSession, G as Granular, O as OntologyHandle, S as Session, W as WSClient } from './client-BMfjRJTs.js';
|
|
2
|
+
import { E as EndpointMode, T as ToolWithHandler, a as EffectHandlerContext, M as ManifestEffectMetamodelSpec, R as ResolvedEffectBehaviors, S as SessionHeapEntry, b as SessionHeapList, c as SessionHeapSnapshot, P as Prompt, d as SessionTranscriptEntry } from './spend-DpRRCrAr.js';
|
|
3
|
+
export { cN as APIError, A as AccessTokenProvider, J as AdoptEnvironmentOptions, bg as ArtifactApprovalDecisionInput, bh as ArtifactApprovalDecisionResult, be as ArtifactApprovalTask, bf as ArtifactApprovalTaskListOptions, bd as ArtifactApprovalTaskStatus, aa as Assignment, ab as AssignmentListResponse, al as Build, an as BuildListResponse, ac as BuildPolicy, ak as BuildStatus, C as ConditionIR, K as ConnectOptions, aV as ConversationActionSuggestion, aZ as ConversationAppendResult, aW as ConversationMessageAction, aY as ConversationMessageInput, aX as ConversationMessagePart, aP as ConversationMessageShowRefs, Q as ConversationSessionInfo, W as ConversationSessionListOptions, V as ConversationSessionListStatus, aQ as ConversationTableCell, aR as ConversationTableColumn, aU as ConversationTableProjection, aT as ConversationTableRow, aS as ConversationTableRowReference, ag as CreateEnvironmentData, a8 as CreatePermissionProfileData, a4 as CreateSandboxData, L as CreateSessionOptions, bV as DefineRelationshipOptions, cO as DeleteResponse, D as DomainState, aE as EffectHandler, aB as EffectInfo, av as EffectInvocationMetadata, au as EffectInvocationMode, aw as EffectSchema, az as EffectVersionSelector, ax as EffectWithHandler, aD as EffectsChangedEvent, af as EnvironmentData, aM as EnvironmentFeedbackRecord, ci as EnvironmentImporter, ch as EnvironmentImporterImportOptions, ah as EnvironmentListResponse, cb as EnvironmentRecordImportSummary, cg as EnvironmentSetupImporterClaim, ce as EnvironmentSetupLifecycleStatus, cf as EnvironmentSetupSummary, cc as EnvironmentSetupTriggerReason, b$ as EnvironmentStateMachineProxy, bZ as EnvironmentStateObservationInput, c0 as EnvironmentStateProxy, bY as EnvironmentStateTarget, b_ as EnvironmentStateUpdateInput, z as GranularAuth, y as GranularOptions, a1 as GranularQuotaPolicy, a2 as GranularQuotaProgress, G as GranularSpendContext, cM as GraphQLResult, aF as InstanceEffectHandler, I as InstanceToolHandler, aO as Job, aK as JobFeedbackInput, aJ as JobFeedbackMetadata, aL as JobFeedbackRecord, aH as JobFeedbackSentiment, aI as JobFeedbackToolCall, aG as JobStatus, aN as JobSubmitResult, ai as Manifest, cB as ManifestApprovalRequiredSpec, cL as ManifestContent, cC as ManifestCreatesSpec, cz as ManifestDryRunSpec, cF as ManifestEffectDeclaration, cE as ManifestEffectSchema, cl as ManifestEnumRuleSpec, cH as ManifestEventStreamDef, cG as ManifestEventTypeDef, cm as ManifestFilterBySpec, cJ as ManifestImport, aj as ManifestListResponse, cI as ManifestOperation, cy as ManifestPostConditionSpec, cj as ManifestPropertySpec, cD as ManifestRelationshipDef, cA as ManifestReverseSpec, cx as ManifestStateMachineSpec, co as ManifestStateMachineStateSpec, cw as ManifestStateMachineTransitionSpec, cq as ManifestStateTransitionActionSpec, cr as ManifestStateTransitionAssigneeSpec, cv as ManifestStateTransitionExpectedOutcomeSpec, cp as ManifestStateTransitionInputBinding, cu as ManifestStateTransitionPermissionSpec, cs as ManifestStateTransitionRelatedStateRequirementSpec, ct as ManifestStateTransitionRequirementsSpec, ck as ManifestValidationOperator, cn as ManifestValidationRuleSpec, cK as ManifestVolume, bp as ManualActionListOptions, bn as ManualActionOccurrence, bo as ManualActionRecordResult, bl as ManualActionRelatedRecord, bj as ManualActionSource, bi as ManualActionStatus, bq as ManualActionSuggestion, br as ManualActionSuggestionOptions, bk as ManualActionTarget, bJ as MarkUserEnvironmentReadOptions, x as MatchedPolicy, bT as ModelRef, N as NormalizedOpenAIUsage, i as OPENAI_MODEL_PRICING_USD_PER_MILLION, O as OpenAIModelPricing, h as OpenAITokenSpend, l as OpenAIUsageSpendEvent, H as OpenEnvironmentOptions, a7 as PermissionProfile, a9 as PermissionProfileListResponse, a6 as PermissionRules, u as PolicyOperator, v as PolicyOrigin, s as PolicyPredicateSource, w as PolicyRuleIR, q as PolicySource, ay as PublishEffectsResult, f as PublishToolsResult, a0 as QuotaLineItemFilter, Z as QuotaPeriod, Y as QuotaScopeType, _ as QuotaStatus, bN as RPCRequest, bQ as RPCRequestFromServer, bO as RPCResponse, ca as RecordImport, c9 as RecordImportItem, c7 as RecordImportItemStatus, c5 as RecordImportOptions, c8 as RecordImportStats, c6 as RecordImportStatus, c4 as RecordImportWriteMode, bm as RecordManualActionInput, bz as RecordMentionInput, bW as RecordObjectOptions, c1 as RecordObjectResult, bX as RecordObjectStateValue, c2 as RecordObjectsChunkInfo, c3 as RecordObjectsOptions, m as RecordOpenAIUsageSpendOptions, o as RecordOpenAIUsageSpendResult, by as RecordSearchOptions, bx as RecordSearchResult, B as RecordUserOptions, bU as RelationshipInfo, at as ResolvedEffectApprovalRequired, ar as ResolvedEffectDryRun, aq as ResolvedEffectPostCondition, as as ResolvedEffectReverse, cd as RunEnvironmentImporterOptions, a3 as Sandbox, a5 as SandboxListResponse, ap as SemanticVersionDiff, ao as SemanticVersionDiffEntry, bc as SessionArtifactApprovalOptions, b6 as SessionArtifactAutonomyPolicy, bb as SessionArtifactExecutionOptions, ba as SessionArtifactExecutionResult, b5 as SessionArtifactKind, b8 as SessionArtifactListOptions, b7 as SessionArtifactRecord, b4 as SessionArtifactStatus, b9 as SessionArtifactValidationResult, bB as SessionCollectionListOptions, bD as SessionCollectionListResult, a_ as SessionConversationMessage, bA as SessionDocumentResult, b1 as SessionFileKind, b3 as SessionFileRecord, b0 as SessionFileSource, b2 as SessionFileStatus, bs as SessionFileUploadOptions, bu as SessionHeapFieldType, bv as SessionHeapFieldValue, bw as SessionHeapVariable, bC as SessionJobListOptions, bt as SessionJobRecord, a$ as SessionTimelineEvent, X as SpendLineItemType, $ as SpendSummary, cP as StreamEvent, cR as StreamStats, cQ as StreamSubscription, F as Subject, bP as SyncMessage, g as ToolHandler, aA as ToolInfo, bR as ToolInvokeParams, bS as ToolResultParams, e as ToolSchema, aC as ToolsChangedEvent, U as User, bF as UserEnvironmentMessagePreview, bE as UserEnvironmentPrompt, bG as UserEnvironmentSessionState, bH as UserEnvironmentState, bI as UserEnvironmentStateOptions, am as Version, ae as VersionTag, ad as VersionTracking, bM as WSClientOptions, bK as WSDisconnectInfo, bL as WSReconnectErrorInfo, p as buildOpenAISpendEventId, k as calculateOpenAITokenSpend, j as getOpenAIModelPricing, n as normalizeOpenAIUsage, r as recordOpenAIUsageSpend, t as toGranularHttpBase } from './spend-DpRRCrAr.js';
|
|
4
4
|
export { BuildGranularAgentSystemPromptInput, GeneratedJobCodeIssue, GranularAgentExecutionCheckpoint, GranularAgentHeapSummaryOptions, GranularAgentManualActionMemorySuggestion, GranularAgentPromptCapabilities, GranularAgentReferentFocus, GranularAgentSessionContext, GranularAgentToolInfo, GranularAgentWorkflowFocus, GranularReasoningTraceChunkResult, GranularReasoningTraceOptions, HarnessContinuationDecision, HarnessControllerBudgets, HarnessProjectionOptions, HarnessPromptLike, HarnessRenderedContinuation, HarnessRenderedPrompt, HarnessTemplate, HarnessTemplateManifest, HarnessTemplateSelectionOptions, HarnessTemplateStatus, HarnessVerifierSnapshot, HarnessVerifierSnapshotInput, ReviewGeneratedJobCodeOptions, buildContinuationInstruction, buildContinuationInstructionFromTemplate, buildGranularAgentCheckpointBlock, buildGranularAgentDomainBlock, buildGranularAgentFileBlock, buildGranularAgentHeapBlock, buildGranularAgentLoopBlock, buildGranularAgentManualActionBlock, buildGranularAgentManualActionMemorySummary, buildGranularAgentReferentBlock, buildGranularAgentRuntimeImportsBlock, buildGranularAgentSessionBlock, buildGranularAgentSystemPrompt, buildGranularAgentSystemPromptFromTemplate, buildGranularAgentToolBlock, buildGranularAgentWorkflowBlock, consumeGranularReasoningOnlyChunk, consumeGranularReasoningTraceChunk, createHarnessVerifierSnapshot, evaluateContinuation, getCurrentClosureId, getDefaultHarnessTemplateId, getExclusivePromptTarget, hasOpenPrompt, hashHarnessTemplateValue, listHarnessTemplates, projectConversationReferentFocus, projectConversationReferentSummary, projectHeapSummary, projectLoopSummary, projectSessionFileSummary, projectWorkflowFocus, projectWorkflowSummary, renderContinuationInstructionFromTemplate, renderGranularAgentSystemPromptFromTemplate, resolveHarnessTemplate, reviewGeneratedJobCode, stripGranularReasoningTrace, validateHarnessTemplateManifest } from './agent-harness.js';
|
|
5
5
|
import '@automerge/automerge';
|
|
6
6
|
import '@automerge/automerge/slim';
|
package/dist/index.js
CHANGED
|
@@ -14309,7 +14309,8 @@ function normalizeEnvironmentSetupSummary(setup) {
|
|
|
14309
14309
|
environmentId: String(setup.environmentId || ""),
|
|
14310
14310
|
sandboxId: String(setup.sandboxId || ""),
|
|
14311
14311
|
subjectId: String(setup.subjectId || ""),
|
|
14312
|
-
triggerReason: setup.triggerReason === "fresh_after_version_update" ? "fresh_after_version_update" : "new_environment",
|
|
14312
|
+
triggerReason: setup.triggerReason === "fresh_after_version_update" ? "fresh_after_version_update" : setup.triggerReason === "explicit_reset" ? "explicit_reset" : "new_environment",
|
|
14313
|
+
operationKey: typeof setup.operationKey === "string" ? setup.operationKey : null,
|
|
14313
14314
|
lifecycleStatus: setup.lifecycleStatus === "completed" || setup.lifecycleStatus === "failed" ? setup.lifecycleStatus : "running",
|
|
14314
14315
|
stage: typeof setup.stage === "string" ? setup.stage : null,
|
|
14315
14316
|
totalObjectsToImport: Number(setup.totalObjectsToImport || 0),
|
|
@@ -15591,6 +15592,7 @@ var Environment = class _Environment {
|
|
|
15591
15592
|
records: recordsToImport,
|
|
15592
15593
|
batchSize: options.batchSize,
|
|
15593
15594
|
setupRunId: options.setupRunId,
|
|
15595
|
+
operationKey: options.operationKey,
|
|
15594
15596
|
writeMode: options.writeMode
|
|
15595
15597
|
})
|
|
15596
15598
|
}
|
|
@@ -16395,6 +16397,107 @@ var Granular = class _Granular {
|
|
|
16395
16397
|
await this.maybeRunEnvironmentImporter(resolved, environment);
|
|
16396
16398
|
return environment;
|
|
16397
16399
|
}
|
|
16400
|
+
/**
|
|
16401
|
+
* Read the active environment selected by Granular for an already-recorded
|
|
16402
|
+
* external user. This is intentionally read-only: browser/login code must
|
|
16403
|
+
* not create subjects or environments as a side effect.
|
|
16404
|
+
*/
|
|
16405
|
+
async getActiveEnvironmentForUser(options) {
|
|
16406
|
+
const sandboxId = options.sandboxId.trim();
|
|
16407
|
+
const tagName = options.tag.trim();
|
|
16408
|
+
const userId = options.userId.trim();
|
|
16409
|
+
if (!sandboxId || !tagName || !userId) {
|
|
16410
|
+
throw new Error(
|
|
16411
|
+
"getActiveEnvironmentForUser() requires sandboxId, tag, and userId."
|
|
16412
|
+
);
|
|
16413
|
+
}
|
|
16414
|
+
const subjects = await this.request(
|
|
16415
|
+
`/control/subjects?identityId=${encodeURIComponent(userId)}`
|
|
16416
|
+
);
|
|
16417
|
+
const subject = (subjects.items || []).find(
|
|
16418
|
+
(item) => item.identityId === userId || item.userId === userId
|
|
16419
|
+
);
|
|
16420
|
+
if (!subject?.subjectId && !subject?.granularId) {
|
|
16421
|
+
return null;
|
|
16422
|
+
}
|
|
16423
|
+
const subjectId = subject.subjectId || subject.granularId;
|
|
16424
|
+
const tags = await this.request(
|
|
16425
|
+
`/control/sandboxes/${encodeURIComponent(sandboxId)}/tags`
|
|
16426
|
+
);
|
|
16427
|
+
const tag = (tags.items || []).find(
|
|
16428
|
+
(item) => item?.name === tagName
|
|
16429
|
+
);
|
|
16430
|
+
if (!tag) return null;
|
|
16431
|
+
const query = new URLSearchParams({
|
|
16432
|
+
tagId: tag.tagId,
|
|
16433
|
+
slot: options.slot?.trim() || "default"
|
|
16434
|
+
});
|
|
16435
|
+
try {
|
|
16436
|
+
const payload = await this.request(
|
|
16437
|
+
`/control/sandboxes/${encodeURIComponent(sandboxId)}/subjects/${encodeURIComponent(subjectId)}/active-environment?${query.toString()}`
|
|
16438
|
+
);
|
|
16439
|
+
return payload.environment ? this.bindEnvironmentHandle(
|
|
16440
|
+
normalizeEnvironmentData(payload.environment)
|
|
16441
|
+
) : null;
|
|
16442
|
+
} catch (error) {
|
|
16443
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
16444
|
+
if (message.includes("404") || message.includes("not found")) {
|
|
16445
|
+
return null;
|
|
16446
|
+
}
|
|
16447
|
+
throw error;
|
|
16448
|
+
}
|
|
16449
|
+
}
|
|
16450
|
+
/**
|
|
16451
|
+
* Register one reviewed, pre-existing environment as the active workspace
|
|
16452
|
+
* for an external user. This is for a controlled migration only: it does
|
|
16453
|
+
* not create an environment and it does not run an importer.
|
|
16454
|
+
*/
|
|
16455
|
+
async adoptEnvironmentForUser(options) {
|
|
16456
|
+
const sandboxId = options.sandboxId.trim();
|
|
16457
|
+
const tagName = options.tag.trim();
|
|
16458
|
+
const userId = options.userId.trim();
|
|
16459
|
+
const environmentId = options.environmentId.trim();
|
|
16460
|
+
if (!sandboxId || !tagName || !userId || !environmentId) {
|
|
16461
|
+
throw new Error(
|
|
16462
|
+
"adoptEnvironmentForUser() requires sandboxId, tag, userId, and environmentId."
|
|
16463
|
+
);
|
|
16464
|
+
}
|
|
16465
|
+
const subjects = await this.request(
|
|
16466
|
+
`/control/subjects?identityId=${encodeURIComponent(userId)}`
|
|
16467
|
+
);
|
|
16468
|
+
const subject = (subjects.items || []).find(
|
|
16469
|
+
(item) => item.identityId === userId || item.userId === userId
|
|
16470
|
+
);
|
|
16471
|
+
if (!subject?.subjectId && !subject?.granularId) {
|
|
16472
|
+
throw new Error(`No Granular subject exists for user ${userId}.`);
|
|
16473
|
+
}
|
|
16474
|
+
const tags = await this.request(`/control/sandboxes/${encodeURIComponent(sandboxId)}/tags`);
|
|
16475
|
+
const tag = (tags.items || []).find(
|
|
16476
|
+
(item) => item?.name === tagName
|
|
16477
|
+
);
|
|
16478
|
+
if (!tag) {
|
|
16479
|
+
throw new Error(`Tag ${tagName} was not found in sandbox ${sandboxId}.`);
|
|
16480
|
+
}
|
|
16481
|
+
const payload = await this.request(
|
|
16482
|
+
"/control/environment-activations/adopt",
|
|
16483
|
+
{
|
|
16484
|
+
method: "POST",
|
|
16485
|
+
body: JSON.stringify({
|
|
16486
|
+
environmentId,
|
|
16487
|
+
subjectId: subject.subjectId || subject.granularId,
|
|
16488
|
+
tagId: tag.tagId,
|
|
16489
|
+
slot: options.slot?.trim() || "default",
|
|
16490
|
+
confirmExistingData: true
|
|
16491
|
+
})
|
|
16492
|
+
}
|
|
16493
|
+
);
|
|
16494
|
+
if (!payload.environment) {
|
|
16495
|
+
throw new Error("Granular did not return the adopted environment.");
|
|
16496
|
+
}
|
|
16497
|
+
return this.bindEnvironmentHandle(
|
|
16498
|
+
normalizeEnvironmentData(payload.environment)
|
|
16499
|
+
);
|
|
16500
|
+
}
|
|
16398
16501
|
/**
|
|
16399
16502
|
* Deprecated compatibility alias for `openEnvironment()`.
|
|
16400
16503
|
*
|
|
@@ -16426,7 +16529,9 @@ var Granular = class _Granular {
|
|
|
16426
16529
|
requestedOntology,
|
|
16427
16530
|
sandboxId: environmentData.sandboxId,
|
|
16428
16531
|
subjectId: environmentData.subjectId,
|
|
16429
|
-
|
|
16532
|
+
externalUserId: environmentData.subjectId,
|
|
16533
|
+
setupTriggerReason: options.reason || "new_environment",
|
|
16534
|
+
setupOperationKey: options.operationKey
|
|
16430
16535
|
},
|
|
16431
16536
|
environment
|
|
16432
16537
|
);
|
|
@@ -16438,20 +16543,17 @@ var Granular = class _Granular {
|
|
|
16438
16543
|
}
|
|
16439
16544
|
return tag;
|
|
16440
16545
|
}
|
|
16441
|
-
buildManagedEnvironmentName(tag, versionId) {
|
|
16442
|
-
|
|
16546
|
+
buildManagedEnvironmentName(tag, versionId, resetKey) {
|
|
16547
|
+
if (!resetKey) {
|
|
16548
|
+
return `__sdk__${tag}__${versionId}__tracked`;
|
|
16549
|
+
}
|
|
16550
|
+
const safeResetKey = resetKey.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 80);
|
|
16551
|
+
return `__sdk__${tag}__${versionId}__reset__${safeResetKey}`;
|
|
16443
16552
|
}
|
|
16444
16553
|
isManagedEnvironmentName(environment, tagName) {
|
|
16445
16554
|
const name = environment.environment || environment.envName || "";
|
|
16446
16555
|
return name.startsWith(`__sdk__${tagName}__`);
|
|
16447
16556
|
}
|
|
16448
|
-
isPinnedToVersion(environment, versionId) {
|
|
16449
|
-
return environment.buildPolicy.mode === "pinned" && (environment.versionId === versionId || environment.buildPolicy.versionId === versionId || environment.buildPolicy.buildId === versionId);
|
|
16450
|
-
}
|
|
16451
|
-
matchesTagTrackedEnvironment(environment, tagName, tagId) {
|
|
16452
|
-
const environmentTagName = environment.tag?.name || environment.buildPolicy.tagName || null;
|
|
16453
|
-
return environment.tagId === tagId || environmentTagName === tagName || environment.environment === tagName || environment.envName === tagName || environment.environment === this.buildManagedEnvironmentName(tagName, environment.versionId) || environment.envName === this.buildManagedEnvironmentName(tagName, environment.versionId);
|
|
16454
|
-
}
|
|
16455
16557
|
sortEnvironmentsByRecency(environments) {
|
|
16456
16558
|
return [...environments].sort(
|
|
16457
16559
|
(left, right) => right.updatedAt - left.updatedAt
|
|
@@ -16501,48 +16603,119 @@ var Granular = class _Granular {
|
|
|
16501
16603
|
`Tag "${tagName}" does not currently point to a build/version.`
|
|
16502
16604
|
);
|
|
16503
16605
|
}
|
|
16606
|
+
const slot = options.slot?.trim() || "default";
|
|
16607
|
+
const resetKey = options.resetKey?.trim() || void 0;
|
|
16608
|
+
const resolveActive = async (operationKey) => {
|
|
16609
|
+
const query = new URLSearchParams({ tagId: tag.tagId, slot });
|
|
16610
|
+
if (operationKey) query.set("operationKey", operationKey);
|
|
16611
|
+
try {
|
|
16612
|
+
const payload = await this.request(
|
|
16613
|
+
`/control/sandboxes/${encodeURIComponent(sandbox.sandboxId)}/subjects/${encodeURIComponent(user.granularId)}/active-environment?${query.toString()}`
|
|
16614
|
+
);
|
|
16615
|
+
return payload.environment ? normalizeEnvironmentData(payload.environment) : null;
|
|
16616
|
+
} catch (error) {
|
|
16617
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
16618
|
+
if (message.includes("404") || message.includes("not found")) {
|
|
16619
|
+
return null;
|
|
16620
|
+
}
|
|
16621
|
+
throw error;
|
|
16622
|
+
}
|
|
16623
|
+
};
|
|
16624
|
+
const activate = async (environment2) => {
|
|
16625
|
+
const payload = await this.request(
|
|
16626
|
+
"/control/environment-activations",
|
|
16627
|
+
{
|
|
16628
|
+
method: "POST",
|
|
16629
|
+
body: JSON.stringify({
|
|
16630
|
+
environmentId: environment2.environmentId,
|
|
16631
|
+
tagId: tag.tagId,
|
|
16632
|
+
slot,
|
|
16633
|
+
operationKey: resetKey,
|
|
16634
|
+
operation: resetKey ? "explicit_reset" : void 0
|
|
16635
|
+
})
|
|
16636
|
+
}
|
|
16637
|
+
);
|
|
16638
|
+
return normalizeEnvironmentData(payload.environment);
|
|
16639
|
+
};
|
|
16640
|
+
if (resetKey) {
|
|
16641
|
+
const resetEnvironment = await resolveActive(resetKey);
|
|
16642
|
+
if (resetEnvironment) {
|
|
16643
|
+
return {
|
|
16644
|
+
environment: resetEnvironment,
|
|
16645
|
+
requestedOntology: ontology,
|
|
16646
|
+
sandboxId: sandbox.sandboxId,
|
|
16647
|
+
subjectId: user.granularId,
|
|
16648
|
+
externalUserId: user.userId,
|
|
16649
|
+
// Retrying an explicit reset must also resume its durable setup run.
|
|
16650
|
+
// Otherwise a Container crash after queue submission would leave a
|
|
16651
|
+
// valid environment permanently marked as "running".
|
|
16652
|
+
setupTriggerReason: "explicit_reset",
|
|
16653
|
+
setupOperationKey: resetKey
|
|
16654
|
+
};
|
|
16655
|
+
}
|
|
16656
|
+
} else {
|
|
16657
|
+
const active = await resolveActive();
|
|
16658
|
+
if (active && (active.versionId === targetVersionId || options.createFreshIfOutdated !== true)) {
|
|
16659
|
+
return {
|
|
16660
|
+
environment: active,
|
|
16661
|
+
requestedOntology: ontology,
|
|
16662
|
+
sandboxId: sandbox.sandboxId,
|
|
16663
|
+
subjectId: user.granularId,
|
|
16664
|
+
externalUserId: user.userId
|
|
16665
|
+
};
|
|
16666
|
+
}
|
|
16667
|
+
}
|
|
16504
16668
|
const allEnvironments = await this.environments.list(sandbox.sandboxId);
|
|
16505
16669
|
const userEnvironments = allEnvironments.filter(
|
|
16506
|
-
(
|
|
16670
|
+
(environment2) => environment2.subjectId === user.granularId
|
|
16507
16671
|
);
|
|
16508
16672
|
const currentMatches = this.sortEnvironmentsByRecency(
|
|
16509
16673
|
userEnvironments.filter(
|
|
16510
|
-
(
|
|
16674
|
+
(environment2) => environment2.tagId === tag.tagId && environment2.versionId === targetVersionId
|
|
16511
16675
|
)
|
|
16512
16676
|
);
|
|
16513
|
-
if (currentMatches.length > 0) {
|
|
16677
|
+
if (!resetKey && currentMatches.length > 0) {
|
|
16678
|
+
const environment2 = await activate(currentMatches[0]);
|
|
16514
16679
|
return {
|
|
16515
|
-
environment:
|
|
16680
|
+
environment: environment2,
|
|
16516
16681
|
requestedOntology: ontology,
|
|
16517
16682
|
sandboxId: sandbox.sandboxId,
|
|
16518
|
-
subjectId: user.granularId
|
|
16683
|
+
subjectId: user.granularId,
|
|
16684
|
+
externalUserId: user.userId
|
|
16519
16685
|
};
|
|
16520
16686
|
}
|
|
16521
16687
|
const outdatedMatches = this.sortEnvironmentsByRecency(
|
|
16522
|
-
userEnvironments.filter(
|
|
16523
|
-
(environment) => this.matchesTagTrackedEnvironment(environment, tagName, tag.tagId)
|
|
16524
|
-
)
|
|
16688
|
+
userEnvironments.filter((environment2) => environment2.tagId === tag.tagId)
|
|
16525
16689
|
);
|
|
16526
16690
|
if (outdatedMatches.length > 0 && options.createFreshIfOutdated !== true) {
|
|
16691
|
+
const environment2 = await activate(outdatedMatches[0]);
|
|
16527
16692
|
return {
|
|
16528
|
-
environment:
|
|
16693
|
+
environment: environment2,
|
|
16529
16694
|
requestedOntology: ontology,
|
|
16530
16695
|
sandboxId: sandbox.sandboxId,
|
|
16531
|
-
subjectId: user.granularId
|
|
16696
|
+
subjectId: user.granularId,
|
|
16697
|
+
externalUserId: user.userId
|
|
16532
16698
|
};
|
|
16533
16699
|
}
|
|
16700
|
+
const created = await this.environments.create(sandbox.sandboxId, {
|
|
16701
|
+
subjectId: user.granularId,
|
|
16702
|
+
environment: this.buildManagedEnvironmentName(
|
|
16703
|
+
tagName,
|
|
16704
|
+
targetVersionId,
|
|
16705
|
+
resetKey
|
|
16706
|
+
),
|
|
16707
|
+
tagId: tag.tagId,
|
|
16708
|
+
permissionProfileId: null
|
|
16709
|
+
});
|
|
16710
|
+
const environment = await activate(created);
|
|
16534
16711
|
return {
|
|
16535
|
-
environment
|
|
16536
|
-
subjectId: user.granularId,
|
|
16537
|
-
environment: this.buildManagedEnvironmentName(tagName, targetVersionId),
|
|
16538
|
-
tagId: tag.tagId,
|
|
16539
|
-
versionId: targetVersionId,
|
|
16540
|
-
permissionProfileId: null
|
|
16541
|
-
}),
|
|
16712
|
+
environment,
|
|
16542
16713
|
requestedOntology: ontology,
|
|
16543
16714
|
sandboxId: sandbox.sandboxId,
|
|
16544
16715
|
subjectId: user.granularId,
|
|
16545
|
-
|
|
16716
|
+
externalUserId: user.userId,
|
|
16717
|
+
setupTriggerReason: resetKey ? "explicit_reset" : outdatedMatches.length > 0 ? "fresh_after_version_update" : "new_environment",
|
|
16718
|
+
setupOperationKey: resetKey
|
|
16546
16719
|
};
|
|
16547
16720
|
}
|
|
16548
16721
|
/**
|
|
@@ -16821,11 +16994,24 @@ var Granular = class _Granular {
|
|
|
16821
16994
|
{
|
|
16822
16995
|
method: "POST",
|
|
16823
16996
|
body: JSON.stringify({
|
|
16824
|
-
triggerReason: resolved.setupTriggerReason
|
|
16997
|
+
triggerReason: resolved.setupTriggerReason,
|
|
16998
|
+
operationKey: resolved.setupOperationKey
|
|
16825
16999
|
})
|
|
16826
17000
|
}
|
|
16827
17001
|
);
|
|
16828
17002
|
const setupRunId = setupRun.setupRunId;
|
|
17003
|
+
let claim = null;
|
|
17004
|
+
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
17005
|
+
claim = await this.request(
|
|
17006
|
+
`/control/environment-setup-runs/${setupRunId}/importer-claim`,
|
|
17007
|
+
{ method: "POST", body: JSON.stringify({}) }
|
|
17008
|
+
);
|
|
17009
|
+
if (claim.action !== "busy") break;
|
|
17010
|
+
await sleep(Math.min(3e4, Math.max(250, claim.retryAfterMs || 1e3)));
|
|
17011
|
+
}
|
|
17012
|
+
if (!claim) {
|
|
17013
|
+
throw new Error(`Unable to claim environment setup run ${setupRunId}.`);
|
|
17014
|
+
}
|
|
16829
17015
|
const updateSetupRun = async (patch) => {
|
|
16830
17016
|
await this.request(
|
|
16831
17017
|
`/control/environment-setup-runs/${setupRunId}`,
|
|
@@ -16835,10 +17021,26 @@ var Granular = class _Granular {
|
|
|
16835
17021
|
}
|
|
16836
17022
|
);
|
|
16837
17023
|
};
|
|
17024
|
+
if (claim.action === "submitted") {
|
|
17025
|
+
const completedSetupRun = await this.request(
|
|
17026
|
+
`/control/environment-setup-runs/${setupRunId}`,
|
|
17027
|
+
{ method: "PATCH", body: JSON.stringify({ markHookCompleted: true }) }
|
|
17028
|
+
);
|
|
17029
|
+
const refreshedEnvironment = await this.environments.get(
|
|
17030
|
+
environment.environmentId
|
|
17031
|
+
);
|
|
17032
|
+
environment.syncEnvironmentData(refreshedEnvironment);
|
|
17033
|
+
return completedSetupRun;
|
|
17034
|
+
}
|
|
17035
|
+
if (claim.action === "busy" || claim.action === "terminal") {
|
|
17036
|
+
return claim.summary;
|
|
17037
|
+
}
|
|
17038
|
+
let importSequence = 0;
|
|
16838
17039
|
const importerContext = {
|
|
16839
17040
|
environmentId: environment.environmentId,
|
|
16840
17041
|
sandboxId: environment.sandboxId,
|
|
16841
17042
|
subjectId: environment.subjectId,
|
|
17043
|
+
externalUserId: resolved.externalUserId,
|
|
16842
17044
|
reason: resolved.setupTriggerReason,
|
|
16843
17045
|
incrementTotalObjectsToImportCount: async (n) => {
|
|
16844
17046
|
const safeIncrement = Math.max(0, Math.trunc(n));
|
|
@@ -16855,7 +17057,10 @@ var Granular = class _Granular {
|
|
|
16855
17057
|
importRecords: async (records, options) => environment.enqueueRecordImport(records, {
|
|
16856
17058
|
batchSize: options?.batchSize,
|
|
16857
17059
|
writeMode: options?.writeMode,
|
|
16858
|
-
setupRunId
|
|
17060
|
+
setupRunId,
|
|
17061
|
+
// Sequence is deterministic for a retry of one importer hook. It
|
|
17062
|
+
// prevents a Container restart from creating a second queue import.
|
|
17063
|
+
operationKey: `${setupRunId}:import:${importSequence++}`
|
|
16859
17064
|
})
|
|
16860
17065
|
};
|
|
16861
17066
|
try {
|