niceeval 0.17.1 → 0.18.0

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 (88) hide show
  1. package/INDEX.md +1 -0
  2. package/dist/adapter.cjs +4 -0
  3. package/dist/adapter.cjs.map +1 -1
  4. package/dist/adapter.d.cts +25 -14
  5. package/dist/adapter.d.mts +25 -14
  6. package/dist/adapter.d.ts +25 -14
  7. package/dist/assertions/measurements.cjs +45 -0
  8. package/dist/assertions/measurements.cjs.map +1 -0
  9. package/dist/assertions/measurements.d.cts +17 -0
  10. package/dist/assertions/measurements.d.mts +17 -0
  11. package/dist/assertions/measurements.d.ts +17 -0
  12. package/dist/assertions/measurements.js +8 -0
  13. package/dist/assertions/measurements.js.map +1 -0
  14. package/dist/define.cjs +2 -0
  15. package/dist/define.cjs.map +1 -1
  16. package/dist/expect/index.cjs +4 -1
  17. package/dist/expect/index.cjs.map +1 -1
  18. package/dist/expect/index.d.cts +2 -0
  19. package/dist/expect/index.d.mts +2 -0
  20. package/dist/expect/index.d.ts +2 -0
  21. package/dist/expect/index.js +20 -16
  22. package/dist/expect/index.mjs +20 -16
  23. package/dist/experiment/host/operations.cjs +3 -1
  24. package/dist/experiment/host/operations.cjs.map +1 -1
  25. package/dist/experiment/host/runtime.cjs +3 -1
  26. package/dist/experiment/host/runtime.cjs.map +1 -1
  27. package/dist/experiment/host/teardown.cjs +1 -0
  28. package/dist/experiment/host/teardown.cjs.map +1 -1
  29. package/dist/index.cjs +3 -19
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +2 -6
  32. package/dist/index.d.mts +2 -6
  33. package/dist/index.d.ts +2 -6
  34. package/dist/index.js +12 -34
  35. package/dist/index.mjs +12 -34
  36. package/dist/model-slots.cjs +19 -0
  37. package/dist/model-slots.cjs.map +1 -1
  38. package/dist/model-slots.d.cts +7 -0
  39. package/dist/model-slots.d.mts +7 -0
  40. package/dist/model-slots.d.ts +7 -0
  41. package/dist/model-slots.js +8 -2
  42. package/dist/o11y/eval-usage.cjs.map +1 -1
  43. package/dist/o11y/eval-usage.d.cts +4 -4
  44. package/dist/o11y/eval-usage.d.mts +4 -4
  45. package/dist/o11y/eval-usage.d.ts +4 -4
  46. package/dist/runner/adoption.cjs +1 -0
  47. package/dist/runner/adoption.cjs.map +1 -1
  48. package/dist/runner/eval-selection.cjs +15 -1
  49. package/dist/runner/eval-selection.cjs.map +1 -1
  50. package/dist/runner/eval-selection.d.cts +4 -0
  51. package/dist/runner/eval-selection.d.mts +4 -0
  52. package/dist/runner/eval-selection.d.ts +4 -0
  53. package/dist/runner/lock.cjs +1 -3
  54. package/dist/runner/lock.cjs.map +1 -1
  55. package/dist/runner/lock.d.cts +0 -2
  56. package/dist/runner/lock.d.mts +0 -2
  57. package/dist/runner/lock.d.ts +0 -2
  58. package/dist/runner/lock.js +14 -16
  59. package/dist/runner/types.cjs.map +1 -1
  60. package/dist/runner/types.d.cts +1 -0
  61. package/dist/runner/types.d.mts +1 -0
  62. package/dist/runner/types.d.ts +1 -0
  63. package/dist/sandbox/docker-profile/registry.cjs +1 -2
  64. package/dist/sandbox/docker-profile/registry.cjs.map +1 -1
  65. package/dist/sandbox/docker-profile/registry.d.cts +0 -1
  66. package/dist/sandbox/docker-profile/registry.d.mts +0 -1
  67. package/dist/sandbox/docker-profile/registry.d.ts +0 -1
  68. package/dist/sandbox/docker-profile/registry.js +2 -4
  69. package/dist/sandbox/index.cjs +1 -2
  70. package/dist/sandbox/index.cjs.map +1 -1
  71. package/dist/sandbox/index.d.cts +1 -1
  72. package/dist/sandbox/index.d.mts +1 -1
  73. package/dist/sandbox/index.d.ts +1 -1
  74. package/dist/sandbox/index.js +32 -34
  75. package/dist/sandbox/index.mjs +32 -34
  76. package/docs-site/zh/examples/integrations/ai-sdk-v7.mdx +5 -5
  77. package/docs-site/zh/examples/integrations/claude-sdk.mdx +5 -5
  78. package/docs-site/zh/examples/integrations/langgraph.mdx +3 -3
  79. package/docs-site/zh/examples/integrations/pi-sdk.mdx +5 -5
  80. package/docs-site/zh/explanation/judge.mdx +1 -1
  81. package/docs-site/zh/index.mdx +18 -0
  82. package/docs-site/zh/introduction.mdx +2 -1
  83. package/docs-site/zh/reference/define-agent.mdx +2 -2
  84. package/docs-site/zh/tutorials/authoring.mdx +2 -1
  85. package/docs-site/zh/tutorials/control-run-cost.mdx +40 -0
  86. package/docs-site/zh/tutorials/upgrade-0-18.mdx +64 -0
  87. package/docs-site/zh/tutorials/verify-judge.mdx +2 -1
  88. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"lock.js","sourceRoot":"","sources":["lock.ts"],"names":[],"mappings":"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","sourcesContent":["import { Clock, Effect, Fiber } from \"effect\";\nimport { type FencedOwner, type ProcessOwnerIdentity, } from \"../coordination/platform/sqlite-coordination.ts\";\nimport { ProjectStateDatabase, type CaseCoordinationFacet } from \"../record/sqlite/project-state-database.ts\";\nimport { currentProcessOwnerIdentity, exactProcessState } from \"./node-process-identity.ts\";\nexport interface CaseLockRecord extends FencedOwner {\n readonly experimentId: string;\n readonly evalId: string;\n readonly startedAt: string;\n readonly heartbeatAt: string;\n}\nexport const CASE_LOCK_HEARTBEAT_INTERVAL_MS = 10000;\n/** Retained for source compatibility; elapsed time never authorizes takeover. */\nexport const CASE_LOCK_EXPIRY_MS = 30000;\nfunction caseId(experimentId: string, evalId: string): string {\n return JSON.stringify([experimentId, evalId]);\n}\nfunction caseEffect<A extends import(\"../record/sqlite/worker-protocol.ts\").StorageWorkerResult>(niceevalRoot: string, operation: (facet: CaseCoordinationFacet) => Promise<A>): Effect.Effect<A, unknown, ProjectStateDatabase> {\n return Effect.flatMap(ProjectStateDatabase, (database) => Effect.flatMap(database.bind(niceevalRoot), (facets) => Effect.tryPromise({ try: () => operation(facets.caseCoordination), catch: (cause) => cause })));\n}\nfunction recordFromProjection(experimentId: string, evalId: string, projection: import(\"../coordination/platform/sqlite-coordination.ts\").CaseLockProjection | undefined): CaseLockRecord | undefined {\n return projection === undefined ? undefined : Object.freeze({\n experimentId,\n evalId,\n ...projection.owner,\n startedAt: projection.acquiredAt,\n heartbeatAt: projection.heartbeatAt,\n });\n}\nexport function readCaseLockEffect(niceevalRoot: string, experimentId: string, evalId: string): Effect.Effect<CaseLockRecord | undefined, unknown, ProjectStateDatabase> {\n return caseEffect(niceevalRoot, (facet) => facet.execute({ _tag: \"case-read\", caseId: caseId(experimentId, evalId) })).pipe(Effect.map((projection) => recordFromProjection(experimentId, evalId, projection as import(\"../coordination/platform/sqlite-coordination.ts\").CaseLockProjection | undefined)));\n}\n/** Heartbeat age is observational and can never establish owner death. */\nexport function isCaseLockExpired(_record: CaseLockRecord, _nowMs: number): boolean { return false; }\nexport interface CaseLockEffectClaim {\n readonly release: Effect.Effect<void, unknown>;\n}\nexport interface AcquireCaseLockEffectResult {\n readonly claim: CaseLockEffectClaim;\n readonly takenOver: boolean;\n}\ntype AcquireOnce = {\n readonly kind: \"acquired\";\n readonly owner: FencedOwner;\n readonly takenOver: boolean;\n} | {\n readonly kind: \"waiting\";\n readonly holder: CaseLockRecord;\n};\nfunction isConflict(cause: unknown): boolean {\n return typeof cause === \"object\" && cause !== null && Reflect.get(cause, \"code\") === \"record-command-conflict\";\n}\nexport function tryAcquireCaseLockOnceEffect(niceevalRoot: string, experimentId: string, evalId: string, identity: ProcessOwnerIdentity, nowMs: number): Effect.Effect<AcquireOnce, unknown, ProjectStateDatabase> {\n const id = caseId(experimentId, evalId);\n const at = new Date(nowMs).toISOString();\n const acquire = caseEffect(niceevalRoot, (facet) => facet.execute<FencedOwner>({\n _tag: \"case-acquire\", caseId: id, owner: identity, at, deadlineEpochMs: Date.now() + 30000,\n })).pipe(Effect.map((owner) => ({ kind: \"acquired\" as const, owner, takenOver: false })));\n return acquire.pipe(Effect.catch((cause) => {\n if (!isConflict(cause))\n return Effect.fail(cause);\n return readCaseLockEffect(niceevalRoot, experimentId, evalId).pipe(Effect.flatMap((holder) => {\n if (holder === undefined)\n return Effect.fail(cause);\n if (exactProcessState(holder) !== \"dead\")\n return Effect.succeed({ kind: \"waiting\" as const, holder });\n return caseEffect(niceevalRoot, (facet) => facet.execute<FencedOwner>({\n _tag: \"case-takeover\", caseId: id, deadOwner: holder, replacement: identity, at,\n deadlineEpochMs: Date.now() + 30000,\n })).pipe(Effect.map((owner) => ({ kind: \"acquired\" as const, owner, takenOver: true })), Effect.catch((takeoverCause) => isConflict(takeoverCause)\n ? readCaseLockEffect(niceevalRoot, experimentId, evalId).pipe(Effect.flatMap((replacement) => replacement === undefined ? Effect.fail(takeoverCause) : Effect.succeed({ kind: \"waiting\" as const, holder: replacement })))\n : Effect.fail(takeoverCause)));\n }));\n }));\n}\nfunction abortError(signal: AbortSignal): Error {\n if (signal.reason instanceof Error)\n return signal.reason;\n const error = new Error(\"aborted while waiting for case lock\");\n error.name = \"AbortError\";\n return error;\n}\nfunction delayOrAbort(milliseconds: number, signal?: AbortSignal): Effect.Effect<void, Error> {\n if (signal === undefined)\n return Effect.sleep(milliseconds);\n if (signal.aborted)\n return Effect.fail(abortError(signal));\n return Effect.raceFirst(Effect.sleep(milliseconds), Effect.callback<void, Error>((resume) => {\n const onAbort = () => resume(Effect.fail(abortError(signal)));\n signal.addEventListener(\"abort\", onAbort, { once: true });\n return Effect.sync(() => signal.removeEventListener(\"abort\", onAbort));\n }));\n}\nconst held = new Map<string, Effect.Effect<void, unknown>>();\nexport function acquireCaseLockEffect(niceevalRoot: string, experimentId: string, evalId: string, identity: Pick<ProcessOwnerIdentity, \"pid\" | \"host\"> & Partial<ProcessOwnerIdentity>, opts: {\n signal?: AbortSignal;\n pollIntervalMs?: number;\n heartbeatIntervalMs?: number;\n onWaitStart?: (holder: CaseLockRecord) => void;\n} = {}): Effect.Effect<AcquireCaseLockEffectResult, unknown, ProjectStateDatabase> {\n const ownerIdentity = identity.ownerId !== undefined && identity.bootId !== undefined && identity.processStart !== undefined\n ? identity as ProcessOwnerIdentity\n : currentProcessOwnerIdentity();\n const heartbeatIntervalMs = opts.heartbeatIntervalMs ?? CASE_LOCK_HEARTBEAT_INTERVAL_MS;\n const pollIntervalMs = opts.pollIntervalMs ?? heartbeatIntervalMs;\n let waitStarted = false;\n const acquire = (): Effect.Effect<{\n owner: FencedOwner;\n takenOver: boolean;\n }, unknown, ProjectStateDatabase> => Effect.suspend(() => Clock.currentTimeMillis.pipe(Effect.flatMap((now) => tryAcquireCaseLockOnceEffect(niceevalRoot, experimentId, evalId, ownerIdentity, now)), Effect.flatMap((result) => {\n if (result.kind === \"acquired\")\n return Effect.succeed({ owner: result.owner, takenOver: result.takenOver });\n if (!waitStarted) {\n waitStarted = true;\n opts.onWaitStart?.(result.holder);\n }\n return delayOrAbort(pollIntervalMs, opts.signal).pipe(Effect.andThen(acquire()));\n })));\n return Effect.uninterruptibleMask((restore) => Effect.gen(function* () {\n const database = yield* ProjectStateDatabase;\n const facets = yield* database.bind(niceevalRoot);\n const acquired = yield* restore(acquire()).pipe(Effect.provideService(ProjectStateDatabase, database));\n const { owner, takenOver } = acquired;\n const id = caseId(experimentId, evalId);\n const key = `${niceevalRoot}\\u0000${id}`;\n let released = false;\n const renew = Clock.currentTimeMillis.pipe(Effect.flatMap((now) => Effect.tryPromise({\n try: () => facets.caseCoordination.execute({ _tag: \"case-heartbeat\", caseId: id, owner, at: new Date(now).toISOString(), deadlineEpochMs: Date.now() + 30000 }),\n catch: (cause) => cause,\n })));\n return yield* Effect.forkChild(Effect.forever(Effect.sleep(heartbeatIntervalMs).pipe(Effect.andThen(renew.pipe(Effect.ignore))))).pipe(Effect.map((fiber) => {\n const release = Effect.uninterruptible(Effect.suspend(() => {\n if (released)\n return Effect.void;\n released = true;\n held.delete(key);\n return Fiber.interrupt(fiber).pipe(Effect.andThen(Effect.tryPromise({\n try: () => facets.caseCoordination.execute<undefined>({ _tag: \"case-release\", caseId: id, owner, deadlineEpochMs: Date.now() + 30000 }),\n catch: (cause) => cause,\n })));\n }));\n held.set(key, release);\n return Object.freeze({ claim: Object.freeze({ release }), takenOver });\n }));\n }));\n}\nexport function drainHeldCaseLocksEffect(): Effect.Effect<number> {\n const releases = [...held.values()];\n return Effect.forEach(releases, (release) => release.pipe(Effect.ignore), { concurrency: \"unbounded\" }).pipe(Effect.as(releases.length));\n}\nexport function pendingHeldCaseLockCount(): number { return held.size; }\n"]}
1
+ {"version":3,"file":"lock.js","sourceRoot":"","sources":["lock.ts"],"names":[],"mappings":"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","sourcesContent":["import { Clock, Effect, Fiber } from \"effect\";\nimport { type FencedOwner, type ProcessOwnerIdentity, } from \"../coordination/platform/sqlite-coordination.ts\";\nimport { ProjectStateDatabase, type CaseCoordinationFacet } from \"../record/sqlite/project-state-database.ts\";\nimport { currentProcessOwnerIdentity, exactProcessState } from \"./node-process-identity.ts\";\nexport interface CaseLockRecord extends FencedOwner {\n readonly experimentId: string;\n readonly evalId: string;\n readonly startedAt: string;\n readonly heartbeatAt: string;\n}\nexport const CASE_LOCK_HEARTBEAT_INTERVAL_MS = 10000;\nfunction caseId(experimentId: string, evalId: string): string {\n return JSON.stringify([experimentId, evalId]);\n}\nfunction caseEffect<A extends import(\"../record/sqlite/worker-protocol.ts\").StorageWorkerResult>(niceevalRoot: string, operation: (facet: CaseCoordinationFacet) => Promise<A>): Effect.Effect<A, unknown, ProjectStateDatabase> {\n return Effect.flatMap(ProjectStateDatabase, (database) => Effect.flatMap(database.bind(niceevalRoot), (facets) => Effect.tryPromise({ try: () => operation(facets.caseCoordination), catch: (cause) => cause })));\n}\nfunction recordFromProjection(experimentId: string, evalId: string, projection: import(\"../coordination/platform/sqlite-coordination.ts\").CaseLockProjection | undefined): CaseLockRecord | undefined {\n return projection === undefined ? undefined : Object.freeze({\n experimentId,\n evalId,\n ...projection.owner,\n startedAt: projection.acquiredAt,\n heartbeatAt: projection.heartbeatAt,\n });\n}\nexport function readCaseLockEffect(niceevalRoot: string, experimentId: string, evalId: string): Effect.Effect<CaseLockRecord | undefined, unknown, ProjectStateDatabase> {\n return caseEffect(niceevalRoot, (facet) => facet.execute({ _tag: \"case-read\", caseId: caseId(experimentId, evalId) })).pipe(Effect.map((projection) => recordFromProjection(experimentId, evalId, projection as import(\"../coordination/platform/sqlite-coordination.ts\").CaseLockProjection | undefined)));\n}\n/** Heartbeat age is observational and can never establish owner death. */\nexport function isCaseLockExpired(_record: CaseLockRecord, _nowMs: number): boolean { return false; }\nexport interface CaseLockEffectClaim {\n readonly release: Effect.Effect<void, unknown>;\n}\nexport interface AcquireCaseLockEffectResult {\n readonly claim: CaseLockEffectClaim;\n readonly takenOver: boolean;\n}\ntype AcquireOnce = {\n readonly kind: \"acquired\";\n readonly owner: FencedOwner;\n readonly takenOver: boolean;\n} | {\n readonly kind: \"waiting\";\n readonly holder: CaseLockRecord;\n};\nfunction isConflict(cause: unknown): boolean {\n return typeof cause === \"object\" && cause !== null && Reflect.get(cause, \"code\") === \"record-command-conflict\";\n}\nexport function tryAcquireCaseLockOnceEffect(niceevalRoot: string, experimentId: string, evalId: string, identity: ProcessOwnerIdentity, nowMs: number): Effect.Effect<AcquireOnce, unknown, ProjectStateDatabase> {\n const id = caseId(experimentId, evalId);\n const at = new Date(nowMs).toISOString();\n const acquire = caseEffect(niceevalRoot, (facet) => facet.execute<FencedOwner>({\n _tag: \"case-acquire\", caseId: id, owner: identity, at, deadlineEpochMs: Date.now() + 30000,\n })).pipe(Effect.map((owner) => ({ kind: \"acquired\" as const, owner, takenOver: false })));\n return acquire.pipe(Effect.catch((cause) => {\n if (!isConflict(cause))\n return Effect.fail(cause);\n return readCaseLockEffect(niceevalRoot, experimentId, evalId).pipe(Effect.flatMap((holder) => {\n if (holder === undefined)\n return Effect.fail(cause);\n if (exactProcessState(holder) !== \"dead\")\n return Effect.succeed({ kind: \"waiting\" as const, holder });\n return caseEffect(niceevalRoot, (facet) => facet.execute<FencedOwner>({\n _tag: \"case-takeover\", caseId: id, deadOwner: holder, replacement: identity, at,\n deadlineEpochMs: Date.now() + 30000,\n })).pipe(Effect.map((owner) => ({ kind: \"acquired\" as const, owner, takenOver: true })), Effect.catch((takeoverCause) => isConflict(takeoverCause)\n ? readCaseLockEffect(niceevalRoot, experimentId, evalId).pipe(Effect.flatMap((replacement) => replacement === undefined ? Effect.fail(takeoverCause) : Effect.succeed({ kind: \"waiting\" as const, holder: replacement })))\n : Effect.fail(takeoverCause)));\n }));\n }));\n}\nfunction abortError(signal: AbortSignal): Error {\n if (signal.reason instanceof Error)\n return signal.reason;\n const error = new Error(\"aborted while waiting for case lock\");\n error.name = \"AbortError\";\n return error;\n}\nfunction delayOrAbort(milliseconds: number, signal?: AbortSignal): Effect.Effect<void, Error> {\n if (signal === undefined)\n return Effect.sleep(milliseconds);\n if (signal.aborted)\n return Effect.fail(abortError(signal));\n return Effect.raceFirst(Effect.sleep(milliseconds), Effect.callback<void, Error>((resume) => {\n const onAbort = () => resume(Effect.fail(abortError(signal)));\n signal.addEventListener(\"abort\", onAbort, { once: true });\n return Effect.sync(() => signal.removeEventListener(\"abort\", onAbort));\n }));\n}\nconst held = new Map<string, Effect.Effect<void, unknown>>();\nexport function acquireCaseLockEffect(niceevalRoot: string, experimentId: string, evalId: string, identity: Pick<ProcessOwnerIdentity, \"pid\" | \"host\"> & Partial<ProcessOwnerIdentity>, opts: {\n signal?: AbortSignal;\n pollIntervalMs?: number;\n heartbeatIntervalMs?: number;\n onWaitStart?: (holder: CaseLockRecord) => void;\n} = {}): Effect.Effect<AcquireCaseLockEffectResult, unknown, ProjectStateDatabase> {\n const ownerIdentity = identity.ownerId !== undefined && identity.bootId !== undefined && identity.processStart !== undefined\n ? identity as ProcessOwnerIdentity\n : currentProcessOwnerIdentity();\n const heartbeatIntervalMs = opts.heartbeatIntervalMs ?? CASE_LOCK_HEARTBEAT_INTERVAL_MS;\n const pollIntervalMs = opts.pollIntervalMs ?? heartbeatIntervalMs;\n let waitStarted = false;\n const acquire = (): Effect.Effect<{\n owner: FencedOwner;\n takenOver: boolean;\n }, unknown, ProjectStateDatabase> => Effect.suspend(() => Clock.currentTimeMillis.pipe(Effect.flatMap((now) => tryAcquireCaseLockOnceEffect(niceevalRoot, experimentId, evalId, ownerIdentity, now)), Effect.flatMap((result) => {\n if (result.kind === \"acquired\")\n return Effect.succeed({ owner: result.owner, takenOver: result.takenOver });\n if (!waitStarted) {\n waitStarted = true;\n opts.onWaitStart?.(result.holder);\n }\n return delayOrAbort(pollIntervalMs, opts.signal).pipe(Effect.andThen(acquire()));\n })));\n return Effect.uninterruptibleMask((restore) => Effect.gen(function* () {\n const database = yield* ProjectStateDatabase;\n const facets = yield* database.bind(niceevalRoot);\n const acquired = yield* restore(acquire()).pipe(Effect.provideService(ProjectStateDatabase, database));\n const { owner, takenOver } = acquired;\n const id = caseId(experimentId, evalId);\n const key = `${niceevalRoot}\\u0000${id}`;\n let released = false;\n const renew = Clock.currentTimeMillis.pipe(Effect.flatMap((now) => Effect.tryPromise({\n try: () => facets.caseCoordination.execute({ _tag: \"case-heartbeat\", caseId: id, owner, at: new Date(now).toISOString(), deadlineEpochMs: Date.now() + 30000 }),\n catch: (cause) => cause,\n })));\n return yield* Effect.forkChild(Effect.forever(Effect.sleep(heartbeatIntervalMs).pipe(Effect.andThen(renew.pipe(Effect.ignore))))).pipe(Effect.map((fiber) => {\n const release = Effect.uninterruptible(Effect.suspend(() => {\n if (released)\n return Effect.void;\n released = true;\n held.delete(key);\n return Fiber.interrupt(fiber).pipe(Effect.andThen(Effect.tryPromise({\n try: () => facets.caseCoordination.execute<undefined>({ _tag: \"case-release\", caseId: id, owner, deadlineEpochMs: Date.now() + 30000 }),\n catch: (cause) => cause,\n })));\n }));\n held.set(key, release);\n return Object.freeze({ claim: Object.freeze({ release }), takenOver });\n }));\n }));\n}\nexport function drainHeldCaseLocksEffect(): Effect.Effect<number> {\n const releases = [...held.values()];\n return Effect.forEach(releases, (release) => release.pipe(Effect.ignore), { concurrency: \"unbounded\" }).pipe(Effect.as(releases.length));\n}\nexport function pendingHeldCaseLockCount(): number { return held.size; }\n"]}
@@ -8,8 +8,6 @@ export interface CaseLockRecord extends FencedOwner {
8
8
  readonly heartbeatAt: string;
9
9
  }
10
10
  export declare const CASE_LOCK_HEARTBEAT_INTERVAL_MS = 10000;
11
- /** Retained for source compatibility; elapsed time never authorizes takeover. */
12
- export declare const CASE_LOCK_EXPIRY_MS = 30000;
13
11
  export declare function readCaseLockEffect(niceevalRoot: string, experimentId: string, evalId: string): Effect.Effect<CaseLockRecord | undefined, unknown, ProjectStateDatabase>;
14
12
  /** Heartbeat age is observational and can never establish owner death. */
15
13
  export declare function isCaseLockExpired(_record: CaseLockRecord, _nowMs: number): boolean;
@@ -8,8 +8,6 @@ export interface CaseLockRecord extends FencedOwner {
8
8
  readonly heartbeatAt: string;
9
9
  }
10
10
  export declare const CASE_LOCK_HEARTBEAT_INTERVAL_MS = 10000;
11
- /** Retained for source compatibility; elapsed time never authorizes takeover. */
12
- export declare const CASE_LOCK_EXPIRY_MS = 30000;
13
11
  export declare function readCaseLockEffect(niceevalRoot: string, experimentId: string, evalId: string): Effect.Effect<CaseLockRecord | undefined, unknown, ProjectStateDatabase>;
14
12
  /** Heartbeat age is observational and can never establish owner death. */
15
13
  export declare function isCaseLockExpired(_record: CaseLockRecord, _nowMs: number): boolean;
@@ -8,8 +8,6 @@ export interface CaseLockRecord extends FencedOwner {
8
8
  readonly heartbeatAt: string;
9
9
  }
10
10
  export declare const CASE_LOCK_HEARTBEAT_INTERVAL_MS = 10000;
11
- /** Retained for source compatibility; elapsed time never authorizes takeover. */
12
- export declare const CASE_LOCK_EXPIRY_MS = 30000;
13
11
  export declare function readCaseLockEffect(niceevalRoot: string, experimentId: string, evalId: string): Effect.Effect<CaseLockRecord | undefined, unknown, ProjectStateDatabase>;
14
12
  /** Heartbeat age is observational and can never establish owner death. */
15
13
  export declare function isCaseLockExpired(_record: CaseLockRecord, _nowMs: number): boolean;
@@ -1,20 +1,18 @@
1
1
  import { createRequire as __niceevalCreateRequire } from "node:module";
2
2
  const __niceevalRequire = __niceevalCreateRequire(import.meta.url);
3
3
  const __niceevalCanonical = __niceevalRequire("./lock.cjs");
4
- const __niceevalExport0 = __niceevalCanonical["CASE_LOCK_EXPIRY_MS"];
5
- export { __niceevalExport0 as CASE_LOCK_EXPIRY_MS };
6
- const __niceevalExport1 = __niceevalCanonical["CASE_LOCK_HEARTBEAT_INTERVAL_MS"];
7
- export { __niceevalExport1 as CASE_LOCK_HEARTBEAT_INTERVAL_MS };
8
- const __niceevalExport2 = __niceevalCanonical["acquireCaseLockEffect"];
9
- export { __niceevalExport2 as acquireCaseLockEffect };
10
- const __niceevalExport3 = __niceevalCanonical["drainHeldCaseLocksEffect"];
11
- export { __niceevalExport3 as drainHeldCaseLocksEffect };
12
- const __niceevalExport4 = __niceevalCanonical["isCaseLockExpired"];
13
- export { __niceevalExport4 as isCaseLockExpired };
14
- const __niceevalExport5 = __niceevalCanonical["pendingHeldCaseLockCount"];
15
- export { __niceevalExport5 as pendingHeldCaseLockCount };
16
- const __niceevalExport6 = __niceevalCanonical["readCaseLockEffect"];
17
- export { __niceevalExport6 as readCaseLockEffect };
18
- const __niceevalExport7 = __niceevalCanonical["tryAcquireCaseLockOnceEffect"];
19
- export { __niceevalExport7 as tryAcquireCaseLockOnceEffect };
4
+ const __niceevalExport0 = __niceevalCanonical["CASE_LOCK_HEARTBEAT_INTERVAL_MS"];
5
+ export { __niceevalExport0 as CASE_LOCK_HEARTBEAT_INTERVAL_MS };
6
+ const __niceevalExport1 = __niceevalCanonical["acquireCaseLockEffect"];
7
+ export { __niceevalExport1 as acquireCaseLockEffect };
8
+ const __niceevalExport2 = __niceevalCanonical["drainHeldCaseLocksEffect"];
9
+ export { __niceevalExport2 as drainHeldCaseLocksEffect };
10
+ const __niceevalExport3 = __niceevalCanonical["isCaseLockExpired"];
11
+ export { __niceevalExport3 as isCaseLockExpired };
12
+ const __niceevalExport4 = __niceevalCanonical["pendingHeldCaseLockCount"];
13
+ export { __niceevalExport4 as pendingHeldCaseLockCount };
14
+ const __niceevalExport5 = __niceevalCanonical["readCaseLockEffect"];
15
+ export { __niceevalExport5 as readCaseLockEffect };
16
+ const __niceevalExport6 = __niceevalCanonical["tryAcquireCaseLockOnceEffect"];
17
+ export { __niceevalExport6 as tryAcquireCaseLockOnceEffect };
20
18
  //# sourceMappingURL=lock.js.map