@granular-software/sdk 0.4.51 → 0.4.53
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 +285 -31
- package/dist/agent-evals.js.map +1 -1
- package/dist/agent-evals.mjs +285 -31
- package/dist/agent-evals.mjs.map +1 -1
- package/dist/cli/index.js +316 -50
- package/dist/{client-djorlOpn.d.mts → client-CfTDojJF.d.mts} +31 -3
- package/dist/{client-NSH-tpNU.d.ts → client-DcRzwuGp.d.ts} +31 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +285 -31
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +285 -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/agent-evals.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as EnvironmentSession, G as Granular } from './client-
|
|
2
|
-
import { G as GranularSpendContext, h as OpenAITokenSpend, P as Prompt,
|
|
1
|
+
import { a as EnvironmentSession, G as Granular } from './client-CfTDojJF.mjs';
|
|
2
|
+
import { G as GranularSpendContext, h as OpenAITokenSpend, P as Prompt, bW as RecordObjectOptions, cL as ManifestContent, c as SessionHeapSnapshot, T as ToolWithHandler, K as ConnectOptions, ag as CreateEnvironmentData, y as GranularOptions } from './spend-DpRRCrAr.mjs';
|
|
3
3
|
import { GranularAgentToolInfo, GeneratedJobCodeIssue, BuildGranularAgentSystemPromptInput, HarnessRenderedPrompt, HarnessRenderedContinuation, HarnessControllerBudgets } from './agent-harness.mjs';
|
|
4
4
|
import '@automerge/automerge';
|
|
5
5
|
import '@automerge/automerge/slim';
|
package/dist/agent-evals.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as EnvironmentSession, G as Granular } from './client-
|
|
2
|
-
import { G as GranularSpendContext, h as OpenAITokenSpend, P as Prompt,
|
|
1
|
+
import { a as EnvironmentSession, G as Granular } from './client-DcRzwuGp.js';
|
|
2
|
+
import { G as GranularSpendContext, h as OpenAITokenSpend, P as Prompt, bW as RecordObjectOptions, cL as ManifestContent, c as SessionHeapSnapshot, T as ToolWithHandler, K as ConnectOptions, ag as CreateEnvironmentData, y as GranularOptions } from './spend-DpRRCrAr.js';
|
|
3
3
|
import { GranularAgentToolInfo, GeneratedJobCodeIssue, BuildGranularAgentSystemPromptInput, HarnessRenderedPrompt, HarnessRenderedContinuation, HarnessControllerBudgets } from './agent-harness.js';
|
|
4
4
|
import '@automerge/automerge';
|
|
5
5
|
import '@automerge/automerge/slim';
|
package/dist/agent-evals.js
CHANGED
|
@@ -14218,7 +14218,8 @@ function normalizeEnvironmentSetupSummary(setup) {
|
|
|
14218
14218
|
environmentId: String(setup.environmentId || ""),
|
|
14219
14219
|
sandboxId: String(setup.sandboxId || ""),
|
|
14220
14220
|
subjectId: String(setup.subjectId || ""),
|
|
14221
|
-
triggerReason: setup.triggerReason === "fresh_after_version_update" ? "fresh_after_version_update" : "new_environment",
|
|
14221
|
+
triggerReason: setup.triggerReason === "fresh_after_version_update" ? "fresh_after_version_update" : setup.triggerReason === "explicit_reset" ? "explicit_reset" : "new_environment",
|
|
14222
|
+
operationKey: typeof setup.operationKey === "string" ? setup.operationKey : null,
|
|
14222
14223
|
lifecycleStatus: setup.lifecycleStatus === "completed" || setup.lifecycleStatus === "failed" ? setup.lifecycleStatus : "running",
|
|
14223
14224
|
stage: typeof setup.stage === "string" ? setup.stage : null,
|
|
14224
14225
|
totalObjectsToImport: Number(setup.totalObjectsToImport || 0),
|
|
@@ -15500,6 +15501,7 @@ var Environment = class _Environment {
|
|
|
15500
15501
|
records: recordsToImport,
|
|
15501
15502
|
batchSize: options.batchSize,
|
|
15502
15503
|
setupRunId: options.setupRunId,
|
|
15504
|
+
operationKey: options.operationKey,
|
|
15503
15505
|
writeMode: options.writeMode
|
|
15504
15506
|
})
|
|
15505
15507
|
}
|
|
@@ -16304,6 +16306,156 @@ var Granular = class _Granular {
|
|
|
16304
16306
|
await this.maybeRunEnvironmentImporter(resolved, environment);
|
|
16305
16307
|
return environment;
|
|
16306
16308
|
}
|
|
16309
|
+
/**
|
|
16310
|
+
* Read the active environment selected by Granular for an already-recorded
|
|
16311
|
+
* external user. This is intentionally read-only: browser/login code must
|
|
16312
|
+
* not create subjects or environments as a side effect.
|
|
16313
|
+
*/
|
|
16314
|
+
async getActiveEnvironmentForUser(options) {
|
|
16315
|
+
const sandboxId = options.sandboxId.trim();
|
|
16316
|
+
const tagName = options.tag.trim();
|
|
16317
|
+
const userId = options.userId.trim();
|
|
16318
|
+
if (!sandboxId || !tagName || !userId) {
|
|
16319
|
+
throw new Error(
|
|
16320
|
+
"getActiveEnvironmentForUser() requires sandboxId, tag, and userId."
|
|
16321
|
+
);
|
|
16322
|
+
}
|
|
16323
|
+
const subjects = await this.request(
|
|
16324
|
+
`/control/subjects?identityId=${encodeURIComponent(userId)}`
|
|
16325
|
+
);
|
|
16326
|
+
const subject = (subjects.items || []).find(
|
|
16327
|
+
(item) => item.identityId === userId || item.userId === userId
|
|
16328
|
+
);
|
|
16329
|
+
if (!subject?.subjectId && !subject?.granularId) {
|
|
16330
|
+
return null;
|
|
16331
|
+
}
|
|
16332
|
+
const subjectId = subject.subjectId || subject.granularId;
|
|
16333
|
+
const tags = await this.request(
|
|
16334
|
+
`/control/sandboxes/${encodeURIComponent(sandboxId)}/tags`
|
|
16335
|
+
);
|
|
16336
|
+
const tag = (tags.items || []).find(
|
|
16337
|
+
(item) => item?.name === tagName
|
|
16338
|
+
);
|
|
16339
|
+
if (!tag) return null;
|
|
16340
|
+
const query = new URLSearchParams({
|
|
16341
|
+
tagId: tag.tagId,
|
|
16342
|
+
slot: options.slot?.trim() || "default"
|
|
16343
|
+
});
|
|
16344
|
+
try {
|
|
16345
|
+
const payload = await this.request(
|
|
16346
|
+
`/control/sandboxes/${encodeURIComponent(sandboxId)}/subjects/${encodeURIComponent(subjectId)}/active-environment?${query.toString()}`
|
|
16347
|
+
);
|
|
16348
|
+
return payload.environment ? this.bindEnvironmentHandle(
|
|
16349
|
+
normalizeEnvironmentData(payload.environment)
|
|
16350
|
+
) : null;
|
|
16351
|
+
} catch (error) {
|
|
16352
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
16353
|
+
if (message.includes("404") || message.includes("not found")) {
|
|
16354
|
+
return null;
|
|
16355
|
+
}
|
|
16356
|
+
throw error;
|
|
16357
|
+
}
|
|
16358
|
+
}
|
|
16359
|
+
/**
|
|
16360
|
+
* Resolve one exact environment only when Granular confirms that it belongs
|
|
16361
|
+
* to the given external user in the requested sandbox (and, optionally,
|
|
16362
|
+
* tag). This is deliberately read-only: callers use it to keep an already
|
|
16363
|
+
* opened delegated workspace stable while a newer active environment is
|
|
16364
|
+
* being prepared in the background.
|
|
16365
|
+
*/
|
|
16366
|
+
async getEnvironmentForUser(options) {
|
|
16367
|
+
const sandboxId = options.sandboxId.trim();
|
|
16368
|
+
const userId = options.userId.trim();
|
|
16369
|
+
const environmentId = options.environmentId.trim();
|
|
16370
|
+
const tagName = options.tag?.trim();
|
|
16371
|
+
if (!sandboxId || !userId || !environmentId) {
|
|
16372
|
+
throw new Error(
|
|
16373
|
+
"getEnvironmentForUser() requires sandboxId, userId, and environmentId."
|
|
16374
|
+
);
|
|
16375
|
+
}
|
|
16376
|
+
const subjects = await this.request(
|
|
16377
|
+
`/control/subjects?identityId=${encodeURIComponent(userId)}`
|
|
16378
|
+
);
|
|
16379
|
+
const subject = (subjects.items || []).find(
|
|
16380
|
+
(item) => item.identityId === userId || item.userId === userId
|
|
16381
|
+
);
|
|
16382
|
+
const subjectId = subject?.subjectId || subject?.granularId;
|
|
16383
|
+
if (!subjectId) return null;
|
|
16384
|
+
let environment;
|
|
16385
|
+
try {
|
|
16386
|
+
environment = await this.environments.get(environmentId);
|
|
16387
|
+
} catch (error) {
|
|
16388
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
16389
|
+
if (message.includes("404") || message.includes("not found")) {
|
|
16390
|
+
return null;
|
|
16391
|
+
}
|
|
16392
|
+
throw error;
|
|
16393
|
+
}
|
|
16394
|
+
if (environment.sandboxId !== sandboxId || environment.subjectId !== subjectId) {
|
|
16395
|
+
return null;
|
|
16396
|
+
}
|
|
16397
|
+
if (tagName) {
|
|
16398
|
+
const tags = await this.request(`/control/sandboxes/${encodeURIComponent(sandboxId)}/tags`);
|
|
16399
|
+
const tag = (tags.items || []).find(
|
|
16400
|
+
(candidate) => candidate?.name === tagName
|
|
16401
|
+
);
|
|
16402
|
+
if (!tag || environment.tagId !== tag.tagId) {
|
|
16403
|
+
return null;
|
|
16404
|
+
}
|
|
16405
|
+
}
|
|
16406
|
+
return this.bindEnvironmentHandle(environment);
|
|
16407
|
+
}
|
|
16408
|
+
/**
|
|
16409
|
+
* Register one reviewed, pre-existing environment as the active workspace
|
|
16410
|
+
* for an external user. This is for a controlled migration only: it does
|
|
16411
|
+
* not create an environment and it does not run an importer.
|
|
16412
|
+
*/
|
|
16413
|
+
async adoptEnvironmentForUser(options) {
|
|
16414
|
+
const sandboxId = options.sandboxId.trim();
|
|
16415
|
+
const tagName = options.tag.trim();
|
|
16416
|
+
const userId = options.userId.trim();
|
|
16417
|
+
const environmentId = options.environmentId.trim();
|
|
16418
|
+
if (!sandboxId || !tagName || !userId || !environmentId) {
|
|
16419
|
+
throw new Error(
|
|
16420
|
+
"adoptEnvironmentForUser() requires sandboxId, tag, userId, and environmentId."
|
|
16421
|
+
);
|
|
16422
|
+
}
|
|
16423
|
+
const subjects = await this.request(
|
|
16424
|
+
`/control/subjects?identityId=${encodeURIComponent(userId)}`
|
|
16425
|
+
);
|
|
16426
|
+
const subject = (subjects.items || []).find(
|
|
16427
|
+
(item) => item.identityId === userId || item.userId === userId
|
|
16428
|
+
);
|
|
16429
|
+
if (!subject?.subjectId && !subject?.granularId) {
|
|
16430
|
+
throw new Error(`No Granular subject exists for user ${userId}.`);
|
|
16431
|
+
}
|
|
16432
|
+
const tags = await this.request(`/control/sandboxes/${encodeURIComponent(sandboxId)}/tags`);
|
|
16433
|
+
const tag = (tags.items || []).find(
|
|
16434
|
+
(item) => item?.name === tagName
|
|
16435
|
+
);
|
|
16436
|
+
if (!tag) {
|
|
16437
|
+
throw new Error(`Tag ${tagName} was not found in sandbox ${sandboxId}.`);
|
|
16438
|
+
}
|
|
16439
|
+
const payload = await this.request(
|
|
16440
|
+
"/control/environment-activations/adopt",
|
|
16441
|
+
{
|
|
16442
|
+
method: "POST",
|
|
16443
|
+
body: JSON.stringify({
|
|
16444
|
+
environmentId,
|
|
16445
|
+
subjectId: subject.subjectId || subject.granularId,
|
|
16446
|
+
tagId: tag.tagId,
|
|
16447
|
+
slot: options.slot?.trim() || "default",
|
|
16448
|
+
confirmExistingData: true
|
|
16449
|
+
})
|
|
16450
|
+
}
|
|
16451
|
+
);
|
|
16452
|
+
if (!payload.environment) {
|
|
16453
|
+
throw new Error("Granular did not return the adopted environment.");
|
|
16454
|
+
}
|
|
16455
|
+
return this.bindEnvironmentHandle(
|
|
16456
|
+
normalizeEnvironmentData(payload.environment)
|
|
16457
|
+
);
|
|
16458
|
+
}
|
|
16307
16459
|
/**
|
|
16308
16460
|
* Deprecated compatibility alias for `openEnvironment()`.
|
|
16309
16461
|
*
|
|
@@ -16335,7 +16487,9 @@ var Granular = class _Granular {
|
|
|
16335
16487
|
requestedOntology,
|
|
16336
16488
|
sandboxId: environmentData.sandboxId,
|
|
16337
16489
|
subjectId: environmentData.subjectId,
|
|
16338
|
-
|
|
16490
|
+
externalUserId: environmentData.subjectId,
|
|
16491
|
+
setupTriggerReason: options.reason || "new_environment",
|
|
16492
|
+
setupOperationKey: options.operationKey
|
|
16339
16493
|
},
|
|
16340
16494
|
environment
|
|
16341
16495
|
);
|
|
@@ -16347,20 +16501,17 @@ var Granular = class _Granular {
|
|
|
16347
16501
|
}
|
|
16348
16502
|
return tag;
|
|
16349
16503
|
}
|
|
16350
|
-
buildManagedEnvironmentName(tag, versionId) {
|
|
16351
|
-
|
|
16504
|
+
buildManagedEnvironmentName(tag, versionId, resetKey) {
|
|
16505
|
+
if (!resetKey) {
|
|
16506
|
+
return `__sdk__${tag}__${versionId}__tracked`;
|
|
16507
|
+
}
|
|
16508
|
+
const safeResetKey = resetKey.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 80);
|
|
16509
|
+
return `__sdk__${tag}__${versionId}__reset__${safeResetKey}`;
|
|
16352
16510
|
}
|
|
16353
16511
|
isManagedEnvironmentName(environment, tagName) {
|
|
16354
16512
|
const name = environment.environment || environment.envName || "";
|
|
16355
16513
|
return name.startsWith(`__sdk__${tagName}__`);
|
|
16356
16514
|
}
|
|
16357
|
-
isPinnedToVersion(environment, versionId) {
|
|
16358
|
-
return environment.buildPolicy.mode === "pinned" && (environment.versionId === versionId || environment.buildPolicy.versionId === versionId || environment.buildPolicy.buildId === versionId);
|
|
16359
|
-
}
|
|
16360
|
-
matchesTagTrackedEnvironment(environment, tagName, tagId) {
|
|
16361
|
-
const environmentTagName = environment.tag?.name || environment.buildPolicy.tagName || null;
|
|
16362
|
-
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);
|
|
16363
|
-
}
|
|
16364
16515
|
sortEnvironmentsByRecency(environments) {
|
|
16365
16516
|
return [...environments].sort(
|
|
16366
16517
|
(left, right) => right.updatedAt - left.updatedAt
|
|
@@ -16410,48 +16561,119 @@ var Granular = class _Granular {
|
|
|
16410
16561
|
`Tag "${tagName}" does not currently point to a build/version.`
|
|
16411
16562
|
);
|
|
16412
16563
|
}
|
|
16564
|
+
const slot = options.slot?.trim() || "default";
|
|
16565
|
+
const resetKey = options.resetKey?.trim() || void 0;
|
|
16566
|
+
const resolveActive = async (operationKey) => {
|
|
16567
|
+
const query = new URLSearchParams({ tagId: tag.tagId, slot });
|
|
16568
|
+
if (operationKey) query.set("operationKey", operationKey);
|
|
16569
|
+
try {
|
|
16570
|
+
const payload = await this.request(
|
|
16571
|
+
`/control/sandboxes/${encodeURIComponent(sandbox.sandboxId)}/subjects/${encodeURIComponent(user.granularId)}/active-environment?${query.toString()}`
|
|
16572
|
+
);
|
|
16573
|
+
return payload.environment ? normalizeEnvironmentData(payload.environment) : null;
|
|
16574
|
+
} catch (error) {
|
|
16575
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
16576
|
+
if (message.includes("404") || message.includes("not found")) {
|
|
16577
|
+
return null;
|
|
16578
|
+
}
|
|
16579
|
+
throw error;
|
|
16580
|
+
}
|
|
16581
|
+
};
|
|
16582
|
+
const activate = async (environment2) => {
|
|
16583
|
+
const payload = await this.request(
|
|
16584
|
+
"/control/environment-activations",
|
|
16585
|
+
{
|
|
16586
|
+
method: "POST",
|
|
16587
|
+
body: JSON.stringify({
|
|
16588
|
+
environmentId: environment2.environmentId,
|
|
16589
|
+
tagId: tag.tagId,
|
|
16590
|
+
slot,
|
|
16591
|
+
operationKey: resetKey,
|
|
16592
|
+
operation: resetKey ? "explicit_reset" : void 0
|
|
16593
|
+
})
|
|
16594
|
+
}
|
|
16595
|
+
);
|
|
16596
|
+
return normalizeEnvironmentData(payload.environment);
|
|
16597
|
+
};
|
|
16598
|
+
if (resetKey) {
|
|
16599
|
+
const resetEnvironment = await resolveActive(resetKey);
|
|
16600
|
+
if (resetEnvironment) {
|
|
16601
|
+
return {
|
|
16602
|
+
environment: resetEnvironment,
|
|
16603
|
+
requestedOntology: ontology,
|
|
16604
|
+
sandboxId: sandbox.sandboxId,
|
|
16605
|
+
subjectId: user.granularId,
|
|
16606
|
+
externalUserId: user.userId,
|
|
16607
|
+
// Retrying an explicit reset must also resume its durable setup run.
|
|
16608
|
+
// Otherwise a Container crash after queue submission would leave a
|
|
16609
|
+
// valid environment permanently marked as "running".
|
|
16610
|
+
setupTriggerReason: "explicit_reset",
|
|
16611
|
+
setupOperationKey: resetKey
|
|
16612
|
+
};
|
|
16613
|
+
}
|
|
16614
|
+
} else {
|
|
16615
|
+
const active = await resolveActive();
|
|
16616
|
+
if (active && (active.versionId === targetVersionId || options.createFreshIfOutdated !== true)) {
|
|
16617
|
+
return {
|
|
16618
|
+
environment: active,
|
|
16619
|
+
requestedOntology: ontology,
|
|
16620
|
+
sandboxId: sandbox.sandboxId,
|
|
16621
|
+
subjectId: user.granularId,
|
|
16622
|
+
externalUserId: user.userId
|
|
16623
|
+
};
|
|
16624
|
+
}
|
|
16625
|
+
}
|
|
16413
16626
|
const allEnvironments = await this.environments.list(sandbox.sandboxId);
|
|
16414
16627
|
const userEnvironments = allEnvironments.filter(
|
|
16415
|
-
(
|
|
16628
|
+
(environment2) => environment2.subjectId === user.granularId
|
|
16416
16629
|
);
|
|
16417
16630
|
const currentMatches = this.sortEnvironmentsByRecency(
|
|
16418
16631
|
userEnvironments.filter(
|
|
16419
|
-
(
|
|
16632
|
+
(environment2) => environment2.tagId === tag.tagId && environment2.versionId === targetVersionId
|
|
16420
16633
|
)
|
|
16421
16634
|
);
|
|
16422
|
-
if (currentMatches.length > 0) {
|
|
16635
|
+
if (!resetKey && currentMatches.length > 0) {
|
|
16636
|
+
const environment2 = await activate(currentMatches[0]);
|
|
16423
16637
|
return {
|
|
16424
|
-
environment:
|
|
16638
|
+
environment: environment2,
|
|
16425
16639
|
requestedOntology: ontology,
|
|
16426
16640
|
sandboxId: sandbox.sandboxId,
|
|
16427
|
-
subjectId: user.granularId
|
|
16641
|
+
subjectId: user.granularId,
|
|
16642
|
+
externalUserId: user.userId
|
|
16428
16643
|
};
|
|
16429
16644
|
}
|
|
16430
16645
|
const outdatedMatches = this.sortEnvironmentsByRecency(
|
|
16431
|
-
userEnvironments.filter(
|
|
16432
|
-
(environment) => this.matchesTagTrackedEnvironment(environment, tagName, tag.tagId)
|
|
16433
|
-
)
|
|
16646
|
+
userEnvironments.filter((environment2) => environment2.tagId === tag.tagId)
|
|
16434
16647
|
);
|
|
16435
16648
|
if (outdatedMatches.length > 0 && options.createFreshIfOutdated !== true) {
|
|
16649
|
+
const environment2 = await activate(outdatedMatches[0]);
|
|
16436
16650
|
return {
|
|
16437
|
-
environment:
|
|
16651
|
+
environment: environment2,
|
|
16438
16652
|
requestedOntology: ontology,
|
|
16439
16653
|
sandboxId: sandbox.sandboxId,
|
|
16440
|
-
subjectId: user.granularId
|
|
16654
|
+
subjectId: user.granularId,
|
|
16655
|
+
externalUserId: user.userId
|
|
16441
16656
|
};
|
|
16442
16657
|
}
|
|
16658
|
+
const created = await this.environments.create(sandbox.sandboxId, {
|
|
16659
|
+
subjectId: user.granularId,
|
|
16660
|
+
environment: this.buildManagedEnvironmentName(
|
|
16661
|
+
tagName,
|
|
16662
|
+
targetVersionId,
|
|
16663
|
+
resetKey
|
|
16664
|
+
),
|
|
16665
|
+
tagId: tag.tagId,
|
|
16666
|
+
permissionProfileId: null
|
|
16667
|
+
});
|
|
16668
|
+
const environment = await activate(created);
|
|
16443
16669
|
return {
|
|
16444
|
-
environment
|
|
16445
|
-
subjectId: user.granularId,
|
|
16446
|
-
environment: this.buildManagedEnvironmentName(tagName, targetVersionId),
|
|
16447
|
-
tagId: tag.tagId,
|
|
16448
|
-
versionId: targetVersionId,
|
|
16449
|
-
permissionProfileId: null
|
|
16450
|
-
}),
|
|
16670
|
+
environment,
|
|
16451
16671
|
requestedOntology: ontology,
|
|
16452
16672
|
sandboxId: sandbox.sandboxId,
|
|
16453
16673
|
subjectId: user.granularId,
|
|
16454
|
-
|
|
16674
|
+
externalUserId: user.userId,
|
|
16675
|
+
setupTriggerReason: resetKey ? "explicit_reset" : outdatedMatches.length > 0 ? "fresh_after_version_update" : "new_environment",
|
|
16676
|
+
setupOperationKey: resetKey
|
|
16455
16677
|
};
|
|
16456
16678
|
}
|
|
16457
16679
|
/**
|
|
@@ -16730,11 +16952,24 @@ var Granular = class _Granular {
|
|
|
16730
16952
|
{
|
|
16731
16953
|
method: "POST",
|
|
16732
16954
|
body: JSON.stringify({
|
|
16733
|
-
triggerReason: resolved.setupTriggerReason
|
|
16955
|
+
triggerReason: resolved.setupTriggerReason,
|
|
16956
|
+
operationKey: resolved.setupOperationKey
|
|
16734
16957
|
})
|
|
16735
16958
|
}
|
|
16736
16959
|
);
|
|
16737
16960
|
const setupRunId = setupRun.setupRunId;
|
|
16961
|
+
let claim = null;
|
|
16962
|
+
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
16963
|
+
claim = await this.request(
|
|
16964
|
+
`/control/environment-setup-runs/${setupRunId}/importer-claim`,
|
|
16965
|
+
{ method: "POST", body: JSON.stringify({}) }
|
|
16966
|
+
);
|
|
16967
|
+
if (claim.action !== "busy") break;
|
|
16968
|
+
await sleep(Math.min(3e4, Math.max(250, claim.retryAfterMs || 1e3)));
|
|
16969
|
+
}
|
|
16970
|
+
if (!claim) {
|
|
16971
|
+
throw new Error(`Unable to claim environment setup run ${setupRunId}.`);
|
|
16972
|
+
}
|
|
16738
16973
|
const updateSetupRun = async (patch) => {
|
|
16739
16974
|
await this.request(
|
|
16740
16975
|
`/control/environment-setup-runs/${setupRunId}`,
|
|
@@ -16744,10 +16979,26 @@ var Granular = class _Granular {
|
|
|
16744
16979
|
}
|
|
16745
16980
|
);
|
|
16746
16981
|
};
|
|
16982
|
+
if (claim.action === "submitted") {
|
|
16983
|
+
const completedSetupRun = await this.request(
|
|
16984
|
+
`/control/environment-setup-runs/${setupRunId}`,
|
|
16985
|
+
{ method: "PATCH", body: JSON.stringify({ markHookCompleted: true }) }
|
|
16986
|
+
);
|
|
16987
|
+
const refreshedEnvironment = await this.environments.get(
|
|
16988
|
+
environment.environmentId
|
|
16989
|
+
);
|
|
16990
|
+
environment.syncEnvironmentData(refreshedEnvironment);
|
|
16991
|
+
return completedSetupRun;
|
|
16992
|
+
}
|
|
16993
|
+
if (claim.action === "busy" || claim.action === "terminal") {
|
|
16994
|
+
return claim.summary;
|
|
16995
|
+
}
|
|
16996
|
+
let importSequence = 0;
|
|
16747
16997
|
const importerContext = {
|
|
16748
16998
|
environmentId: environment.environmentId,
|
|
16749
16999
|
sandboxId: environment.sandboxId,
|
|
16750
17000
|
subjectId: environment.subjectId,
|
|
17001
|
+
externalUserId: resolved.externalUserId,
|
|
16751
17002
|
reason: resolved.setupTriggerReason,
|
|
16752
17003
|
incrementTotalObjectsToImportCount: async (n) => {
|
|
16753
17004
|
const safeIncrement = Math.max(0, Math.trunc(n));
|
|
@@ -16764,7 +17015,10 @@ var Granular = class _Granular {
|
|
|
16764
17015
|
importRecords: async (records, options) => environment.enqueueRecordImport(records, {
|
|
16765
17016
|
batchSize: options?.batchSize,
|
|
16766
17017
|
writeMode: options?.writeMode,
|
|
16767
|
-
setupRunId
|
|
17018
|
+
setupRunId,
|
|
17019
|
+
// Sequence is deterministic for a retry of one importer hook. It
|
|
17020
|
+
// prevents a Container restart from creating a second queue import.
|
|
17021
|
+
operationKey: `${setupRunId}:import:${importSequence++}`
|
|
16768
17022
|
})
|
|
16769
17023
|
};
|
|
16770
17024
|
try {
|