@openpond/evals 0.10.2 → 0.10.4
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/LEARNING.md +39 -0
- package/dist/learning/contracts.js +1 -0
- package/dist/learning/index.js +4 -0
- package/dist/learning/iteration-candidate-decision.js +51 -0
- package/dist/learning/repository.js +2 -0
- package/dist/learning/schedule-contracts.js +45 -0
- package/dist/learning/schedule-service.js +31 -0
- package/dist/learning/schedule-worker.js +96 -0
- package/dist/learning/service.js +7 -0
- package/dist/types/learning/contracts.d.ts +10 -0
- package/dist/types/learning/contracts.d.ts.map +1 -1
- package/dist/types/learning/index.d.ts +4 -0
- package/dist/types/learning/index.d.ts.map +1 -1
- package/dist/types/learning/iteration-candidate-decision.d.ts +94 -0
- package/dist/types/learning/iteration-candidate-decision.d.ts.map +1 -0
- package/dist/types/learning/repository.d.ts +71 -1
- package/dist/types/learning/repository.d.ts.map +1 -1
- package/dist/types/learning/schedule-contracts.d.ts +69 -0
- package/dist/types/learning/schedule-contracts.d.ts.map +1 -0
- package/dist/types/learning/schedule-service.d.ts +30 -0
- package/dist/types/learning/schedule-service.d.ts.map +1 -0
- package/dist/types/learning/schedule-worker.d.ts +12 -0
- package/dist/types/learning/schedule-worker.d.ts.map +1 -0
- package/dist/types/learning/service.d.ts.map +1 -1
- package/dist/types/learning/transport.d.ts +72 -2
- package/dist/types/learning/transport.d.ts.map +1 -1
- package/package.json +1 -1
- package/schemas/learning/v1/iteration.schema.json +12 -0
- package/schemas/learning/v1/read-request.schema.json +2 -0
- package/schemas/learning/v1/schedule.schema.json +188 -0
- package/schemas/learning/v1/schedule_fire.schema.json +163 -0
package/LEARNING.md
CHANGED
|
@@ -218,3 +218,42 @@ A successful execution without an adapter becomes `completed_without_candidate`;
|
|
|
218
218
|
it does not fabricate a version or an improvement. Provider adapters, timers,
|
|
219
219
|
candidate-decision reconciliation and product controls must be connected by the
|
|
220
220
|
host; this shared worker alone does not enable hosted scheduling.
|
|
221
|
+
|
|
222
|
+
### Retained candidate decisions
|
|
223
|
+
|
|
224
|
+
`reconcileLearningCandidateDecision` lets a trusted host reconcile an already
|
|
225
|
+
authorized, verified provider decision into the learning chain. The host must
|
|
226
|
+
verify the decision's immutable hash, ownership, revision and retained training
|
|
227
|
+
evidence before invoking this boundary; it is not a public review command.
|
|
228
|
+
Reconciliation matches the exact execution, candidate, evaluation and terminal
|
|
229
|
+
cleanup receipt, retains the decision reference on the iteration, and records
|
|
230
|
+
`accepted` or `rejected`. It releases the chain only when that iteration still
|
|
231
|
+
owns it. Duplicate observations are idempotent, older decision revisions cannot
|
|
232
|
+
overwrite newer ones, and contradictory observations at the same revision fail.
|
|
233
|
+
This operation does not change the training parent or activate serving.
|
|
234
|
+
|
|
235
|
+
### Durable learning schedules
|
|
236
|
+
|
|
237
|
+
Policy publication atomically synchronizes a `schedule` resource. Enabling
|
|
238
|
+
scheduled training requires reviewer authority, including batched publication,
|
|
239
|
+
because it authorizes the same reservation as manual Train. The timer preserves
|
|
240
|
+
its pending occurrence through ordinary policy edits. Pause removes its pending
|
|
241
|
+
due time; resume, cadence changes and execution-owner changes start a future
|
|
242
|
+
occurrence. `synchronizeLearningSchedule` can initialize an existing current
|
|
243
|
+
policy, but refuses stale policies and does not reset an unchanged timer.
|
|
244
|
+
|
|
245
|
+
`createLearningScheduleWorker` runs a typed learning reservation in the same
|
|
246
|
+
repository transaction as an immutable `schedule_fire` and timer advance.
|
|
247
|
+
Duplicate replicas and restarts therefore cannot consume a second batch for an
|
|
248
|
+
occurrence. Downtime retains the original due time and coalesces subsequent
|
|
249
|
+
missed occurrences into one fire, recording the covered time and count.
|
|
250
|
+
Insufficient approved evidence records waiting without reserved spend. An active
|
|
251
|
+
chain, cooldown or daily budget limit records an explicit skip. Review approval
|
|
252
|
+
does not move the next due time or independently start training.
|
|
253
|
+
|
|
254
|
+
Other errors roll back reservation mutations and keep the original occurrence
|
|
255
|
+
for bounded retries. Exhausting the policy retry limit blocks the timer with a
|
|
256
|
+
retained diagnostic; a new reviewed policy revision may resume it. Hosts must
|
|
257
|
+
poll due timers for their execution owner and supply an authorized actor. This
|
|
258
|
+
worker does not execute a Work prompt or submit a provider Job; the existing
|
|
259
|
+
iteration dispatch worker owns that next transition.
|
|
@@ -232,6 +232,7 @@ export const LearningIterationSchema = z.object({
|
|
|
232
232
|
trainingJob: ImmutableReleaseRefSchema.nullable(),
|
|
233
233
|
evaluationJob: ImmutableReleaseRefSchema.nullable(),
|
|
234
234
|
candidateVersion: ImmutableReleaseRefSchema.nullable(),
|
|
235
|
+
candidateDecision: LearningRevisionRefSchema.nullable().default(null),
|
|
235
236
|
dispatchId: ReleaseIdSchema,
|
|
236
237
|
retryCount: z.number().int().nonnegative(),
|
|
237
238
|
spendUsd: z.number().nonnegative(),
|
package/dist/learning/index.js
CHANGED
|
@@ -15,3 +15,7 @@ export * from "./reward-fixture-executor.js";
|
|
|
15
15
|
export * from "./iteration-reservation-contracts.js";
|
|
16
16
|
export * from "./iteration-dispatch-contracts.js";
|
|
17
17
|
export * from "./iteration-dispatch-worker.js";
|
|
18
|
+
export * from "./iteration-candidate-decision.js";
|
|
19
|
+
export * from "./schedule-contracts.js";
|
|
20
|
+
export * from "./schedule-service.js";
|
|
21
|
+
export * from "./schedule-worker.js";
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ImmutableReleaseRefSchema, ReleaseIdSchema } from "@openpond/harness";
|
|
3
|
+
import { LearningIterationSchema, LearningRevisionRefSchema } from "./contracts.js";
|
|
4
|
+
import { LearningDomainError } from "./errors.js";
|
|
5
|
+
import { LearningChainSchema } from "./iteration-reservation-contracts.js";
|
|
6
|
+
import { requireLearningResource } from "./repository.js";
|
|
7
|
+
export const LearningCandidateDecisionObservationSchema = z.object({
|
|
8
|
+
scope: ReleaseIdSchema,
|
|
9
|
+
iterationId: ReleaseIdSchema,
|
|
10
|
+
decision: LearningRevisionRefSchema,
|
|
11
|
+
outcome: z.enum(["accepted", "rejected"]),
|
|
12
|
+
execution: ImmutableReleaseRefSchema,
|
|
13
|
+
candidate: ImmutableReleaseRefSchema,
|
|
14
|
+
evaluation: ImmutableReleaseRefSchema,
|
|
15
|
+
receipt: ImmutableReleaseRefSchema,
|
|
16
|
+
}).strict();
|
|
17
|
+
/** Trusted host boundary: verify the provider's immutable decision and ownership
|
|
18
|
+
* before calling. This reconciles retained evidence; it does not authorize a
|
|
19
|
+
* review, accept a model automatically, or activate serving. */
|
|
20
|
+
export async function reconcileLearningCandidateDecision(repository, value, options = {}) {
|
|
21
|
+
const input = LearningCandidateDecisionObservationSchema.parse(value);
|
|
22
|
+
return repository.transaction(input.scope, async (tx) => {
|
|
23
|
+
const iteration = await requireLearningResource(tx, "iteration", input.iterationId);
|
|
24
|
+
const dispatch = await requireLearningResource(tx, "dispatch", iteration.dispatchId);
|
|
25
|
+
const same = (left, right) => left?.id === right.id && left.contentHash === right.contentHash;
|
|
26
|
+
if (dispatch.iterationId !== iteration.id || dispatch.state !== "settled" ||
|
|
27
|
+
!same(iteration.trainingJob, input.execution) || !same(dispatch.execution, input.execution) ||
|
|
28
|
+
!same(iteration.candidateVersion, input.candidate) || !same(iteration.evaluationJob, input.evaluation) ||
|
|
29
|
+
!same(dispatch.terminalReceipt, input.receipt))
|
|
30
|
+
throw new LearningDomainError("learning_candidate_decision_evidence_mismatch", 409);
|
|
31
|
+
if (!["candidate_ready", "accepted", "rejected"].includes(iteration.status))
|
|
32
|
+
throw new LearningDomainError("learning_candidate_not_reviewable", 409);
|
|
33
|
+
const previous = iteration.candidateDecision;
|
|
34
|
+
if (previous && input.decision.revision < previous.revision)
|
|
35
|
+
return iteration;
|
|
36
|
+
if (previous && input.decision.revision === previous.revision) {
|
|
37
|
+
if (!same(previous, input.decision) || iteration.status !== input.outcome)
|
|
38
|
+
throw new LearningDomainError("learning_candidate_decision_revision_conflict", 409);
|
|
39
|
+
return iteration;
|
|
40
|
+
}
|
|
41
|
+
const now = (options.now ?? (() => new Date().toISOString()))();
|
|
42
|
+
const updated = LearningIterationSchema.parse({ ...iteration, revision: iteration.revision + 1,
|
|
43
|
+
candidateDecision: input.decision, status: input.outcome, updatedAt: now });
|
|
44
|
+
await tx.put("iteration", updated, iteration.revision, { parentId: dispatch.chainId, status: updated.status });
|
|
45
|
+
const chain = await requireLearningResource(tx, "chain", dispatch.chainId);
|
|
46
|
+
if (chain.activeIterationId === iteration.id)
|
|
47
|
+
await tx.put("chain", LearningChainSchema.parse({ ...chain,
|
|
48
|
+
revision: chain.revision + 1, activeIterationId: null, updatedAt: now }), chain.revision, { parentId: chain.modelProjectId });
|
|
49
|
+
return updated;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LearningChainSchema, LearningConsumptionSchema, LearningIterationReservationSchema } from "./iteration-reservation-contracts.js";
|
|
2
2
|
import { LearningIterationDispatchSchema } from "./iteration-dispatch-contracts.js";
|
|
3
|
+
import { LearningScheduleSchema, LearningScheduleFireSchema } from "./schedule-contracts.js";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
import { contentHash } from "@openpond/harness";
|
|
5
6
|
import { assertLearningContentHash, LearningSourceSchema, TaskAdmissionDecisionSchema, TaskBatchSchema, TaskDefinitionSchema, TaskEvidenceSchema, TaskFeedbackSchema, TaskGradeRunSchema, LearningPolicySchema, LearningIterationSchema } from "./contracts.js";
|
|
@@ -18,6 +19,7 @@ export const learningResourceSchemas = {
|
|
|
18
19
|
decision: TaskAdmissionDecisionSchema, batch: TaskBatchSchema, policy: LearningPolicySchema,
|
|
19
20
|
chain: LearningChainSchema, consumption: LearningConsumptionSchema, reservation: LearningIterationReservationSchema,
|
|
20
21
|
dispatch: LearningIterationDispatchSchema,
|
|
22
|
+
schedule: LearningScheduleSchema, schedule_fire: LearningScheduleFireSchema,
|
|
21
23
|
iteration: LearningIterationSchema, grade: TaskGradeRunSchema, package: TasksetReleaseSchema,
|
|
22
24
|
};
|
|
23
25
|
export const LearningResourceKindSchema = z.enum(Object.keys(learningResourceSchemas));
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ReleaseHashSchema, ReleaseIdSchema, ReleaseTimestampSchema } from "@openpond/harness";
|
|
3
|
+
import { LearningRevisionRefSchema } from "./contracts.js";
|
|
4
|
+
/** The durable timer is operational state; every fire retains its own policy. */
|
|
5
|
+
export const LearningScheduleSchema = z.object({
|
|
6
|
+
schemaVersion: z.literal("openpond.learningSchedule.v1"),
|
|
7
|
+
id: ReleaseIdSchema,
|
|
8
|
+
revision: z.number().int().positive(),
|
|
9
|
+
policy: LearningRevisionRefSchema,
|
|
10
|
+
modelProjectId: ReleaseIdSchema,
|
|
11
|
+
executionOwner: z.enum(["local", "hosted"]),
|
|
12
|
+
state: z.enum(["scheduled", "disabled", "blocked"]),
|
|
13
|
+
intervalSeconds: z.number().int().min(60).max(31_536_000).nullable(),
|
|
14
|
+
nextRunAt: ReleaseTimestampSchema.nullable(),
|
|
15
|
+
lastFire: LearningRevisionRefSchema.nullable(),
|
|
16
|
+
consecutiveFailures: z.number().int().nonnegative(),
|
|
17
|
+
nextAttemptAt: ReleaseTimestampSchema.nullable(),
|
|
18
|
+
lastError: z.string().max(20_000).nullable(),
|
|
19
|
+
createdAt: ReleaseTimestampSchema,
|
|
20
|
+
updatedAt: ReleaseTimestampSchema,
|
|
21
|
+
}).strict().superRefine((value, context) => {
|
|
22
|
+
if (value.state !== "disabled" && (!value.intervalSeconds || !value.nextRunAt))
|
|
23
|
+
context.addIssue({ code: "custom", path: ["nextRunAt"], message: "An active timer must retain its cadence and due time." });
|
|
24
|
+
if (value.state === "disabled" && value.nextRunAt)
|
|
25
|
+
context.addIssue({ code: "custom", path: ["nextRunAt"], message: "A disabled timer cannot have a pending occurrence." });
|
|
26
|
+
});
|
|
27
|
+
/** Immutable occurrence evidence survives timer edits and coalesced downtime. */
|
|
28
|
+
export const LearningScheduleFireSchema = z.object({
|
|
29
|
+
schemaVersion: z.literal("openpond.learningScheduleFire.v1"),
|
|
30
|
+
id: ReleaseIdSchema,
|
|
31
|
+
revision: z.literal(1),
|
|
32
|
+
scheduleId: ReleaseIdSchema,
|
|
33
|
+
policy: LearningRevisionRefSchema,
|
|
34
|
+
scheduledAt: ReleaseTimestampSchema,
|
|
35
|
+
coalescedThroughAt: ReleaseTimestampSchema,
|
|
36
|
+
coalescedCount: z.number().int().nonnegative(),
|
|
37
|
+
outcome: z.enum(["reserved", "waiting_for_data", "waiting_for_review", "skipped"]),
|
|
38
|
+
reason: z.enum(["active_iteration", "cooldown", "daily_budget"]).nullable(),
|
|
39
|
+
iteration: z.object({ id: ReleaseIdSchema, revision: z.number().int().positive() }).strict().nullable(),
|
|
40
|
+
createdAt: ReleaseTimestampSchema,
|
|
41
|
+
contentHash: ReleaseHashSchema,
|
|
42
|
+
}).strict().superRefine((value, context) => {
|
|
43
|
+
if ((value.outcome === "skipped") !== Boolean(value.reason) || (value.outcome !== "skipped") !== Boolean(value.iteration))
|
|
44
|
+
context.addIssue({ code: "custom", path: ["outcome"], message: "A fire retains either its reservation or its explicit skip reason." });
|
|
45
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { contentHash } from "@openpond/harness";
|
|
2
|
+
import { assertLearningContentHash, learningRef, sameLearningRef } from "./contracts.js";
|
|
3
|
+
import { LearningScheduleSchema } from "./schedule-contracts.js";
|
|
4
|
+
import { LearningDomainError } from "./errors.js";
|
|
5
|
+
import { requireLearningResource } from "./repository.js";
|
|
6
|
+
export function learningScheduleId(policyId) { return `schedule-${contentHash(policyId)}`; }
|
|
7
|
+
/** Called atomically with policy publication. No external timer or Work is made. */
|
|
8
|
+
export async function synchronizeLearningSchedule(tx, policy, now) {
|
|
9
|
+
assertLearningContentHash(policy);
|
|
10
|
+
const current = await requireLearningResource(tx, "policy", policy.id);
|
|
11
|
+
if (!sameLearningRef(learningRef(current), learningRef(policy)))
|
|
12
|
+
throw new LearningDomainError("learning_policy_revision_stale", 409);
|
|
13
|
+
const id = learningScheduleId(policy.id);
|
|
14
|
+
const previous = await tx.get("schedule", id);
|
|
15
|
+
if (previous && sameLearningRef(previous.policy, learningRef(policy)))
|
|
16
|
+
return previous;
|
|
17
|
+
const intervalSeconds = policy.trigger.kind === "schedule" ? policy.trigger.intervalSeconds : null;
|
|
18
|
+
const enabled = policy.enabled && policy.automation.train && intervalSeconds !== null;
|
|
19
|
+
const preserveDue = previous?.nextRunAt && previous.intervalSeconds === intervalSeconds
|
|
20
|
+
&& previous.executionOwner === policy.executionOwner;
|
|
21
|
+
const schedule = LearningScheduleSchema.parse({
|
|
22
|
+
schemaVersion: "openpond.learningSchedule.v1", id, revision: (previous?.revision ?? 0) + 1,
|
|
23
|
+
policy: learningRef(policy), modelProjectId: policy.modelProjectId, executionOwner: policy.executionOwner,
|
|
24
|
+
state: enabled ? "scheduled" : "disabled", intervalSeconds,
|
|
25
|
+
nextRunAt: enabled ? preserveDue ? previous.nextRunAt : new Date(Date.parse(now) + intervalSeconds * 1_000).toISOString() : null,
|
|
26
|
+
lastFire: previous?.lastFire ?? null, consecutiveFailures: 0, nextAttemptAt: null, lastError: null,
|
|
27
|
+
createdAt: previous?.createdAt ?? now, updatedAt: now,
|
|
28
|
+
});
|
|
29
|
+
await tx.put("schedule", schedule, previous?.revision ?? 0, { parentId: policy.modelProjectId, status: schedule.state });
|
|
30
|
+
return schedule;
|
|
31
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { contentHash } from "@openpond/harness";
|
|
2
|
+
import { learningRef, sealLearningContent } from "./contracts.js";
|
|
3
|
+
import { LearningDomainError } from "./errors.js";
|
|
4
|
+
import { reserveLearningIteration } from "./iteration-reservation-service.js";
|
|
5
|
+
import { LearningScheduleFireSchema, LearningScheduleSchema } from "./schedule-contracts.js";
|
|
6
|
+
import { requireLearningRelease, requireLearningResource } from "./repository.js";
|
|
7
|
+
const skipReasons = new Map([
|
|
8
|
+
["learning_iteration_active", "active_iteration"], ["learning_iteration_cooldown", "cooldown"],
|
|
9
|
+
["learning_daily_budget_exhausted", "daily_budget"],
|
|
10
|
+
]);
|
|
11
|
+
/** Like a durable scheduled Work fire, the occurrence and timer advance commit
|
|
12
|
+
* together. Here the typed target is a learning reservation, never a prompt or
|
|
13
|
+
* provider submission. All work inside the transaction is repository-only. */
|
|
14
|
+
export function createLearningScheduleWorker(repository, options) {
|
|
15
|
+
const now = options.now ?? (() => new Date().toISOString());
|
|
16
|
+
async function run(scope, scheduleId, actorId) {
|
|
17
|
+
let attempt = null;
|
|
18
|
+
try {
|
|
19
|
+
return await repository.transaction(scope, async (tx) => {
|
|
20
|
+
const schedule = await requireLearningResource(tx, "schedule", scheduleId);
|
|
21
|
+
if (schedule.executionOwner !== options.executionOwner)
|
|
22
|
+
throw new LearningDomainError("learning_execution_owner_mismatch", 409);
|
|
23
|
+
const timestamp = now();
|
|
24
|
+
const time = Date.parse(timestamp);
|
|
25
|
+
if (schedule.state !== "scheduled" || !schedule.nextRunAt || Date.parse(schedule.nextRunAt) > time
|
|
26
|
+
|| (schedule.nextAttemptAt && Date.parse(schedule.nextAttemptAt) > time))
|
|
27
|
+
return schedule;
|
|
28
|
+
attempt = { schedule, maxRetries: 0 };
|
|
29
|
+
const policy = await requireLearningRelease(tx, "policy", schedule.policy);
|
|
30
|
+
attempt.maxRetries = policy.limits.maxRetries;
|
|
31
|
+
if (policy.executionOwner !== schedule.executionOwner || policy.trigger.kind !== "schedule"
|
|
32
|
+
|| policy.trigger.intervalSeconds !== schedule.intervalSeconds)
|
|
33
|
+
throw new LearningDomainError("learning_schedule_policy_mismatch", 409);
|
|
34
|
+
const scheduledAt = schedule.nextRunAt;
|
|
35
|
+
const interval = schedule.intervalSeconds * 1_000;
|
|
36
|
+
const due = Date.parse(scheduledAt);
|
|
37
|
+
const coalescedCount = Math.floor((time - due) / interval);
|
|
38
|
+
const id = `schedule-fire-${contentHash([schedule.id, scheduledAt])}`;
|
|
39
|
+
let outcome = "skipped";
|
|
40
|
+
let reason = null;
|
|
41
|
+
let iteration = null;
|
|
42
|
+
try {
|
|
43
|
+
const pointers = await reserveLearningIteration(tx, { action: "reserve_iteration", operationId: id,
|
|
44
|
+
policy: schedule.policy, trigger: { kind: "schedule", scheduledAt } }, actorId, timestamp);
|
|
45
|
+
const pointer = pointers.find(value => value.kind === "iteration");
|
|
46
|
+
if (!pointer)
|
|
47
|
+
throw new LearningDomainError("learning_schedule_reservation_missing", 409);
|
|
48
|
+
const reservation = await requireLearningResource(tx, "reservation", pointer.id);
|
|
49
|
+
outcome = reservation.outcome;
|
|
50
|
+
iteration = { id: pointer.id, revision: pointer.revision };
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
// These admission checks run before reservation mutations. Every other
|
|
54
|
+
// error must roll back the whole fire, including any partial batch.
|
|
55
|
+
const skip = error instanceof LearningDomainError ? skipReasons.get(error.code) : undefined;
|
|
56
|
+
if (!skip)
|
|
57
|
+
throw error;
|
|
58
|
+
reason = skip;
|
|
59
|
+
}
|
|
60
|
+
const fire = LearningScheduleFireSchema.parse(sealLearningContent({
|
|
61
|
+
schemaVersion: "openpond.learningScheduleFire.v1", id, revision: 1, scheduleId,
|
|
62
|
+
policy: schedule.policy, scheduledAt, coalescedThroughAt: new Date(due + coalescedCount * interval).toISOString(),
|
|
63
|
+
coalescedCount, outcome, reason, iteration, createdAt: timestamp,
|
|
64
|
+
}));
|
|
65
|
+
await tx.put("schedule_fire", fire, 0, { parentId: schedule.id, status: outcome });
|
|
66
|
+
const updated = LearningScheduleSchema.parse({ ...schedule, revision: schedule.revision + 1,
|
|
67
|
+
nextRunAt: new Date(due + (coalescedCount + 1) * interval).toISOString(), lastFire: learningRef(fire),
|
|
68
|
+
consecutiveFailures: 0, nextAttemptAt: null, lastError: null, updatedAt: timestamp });
|
|
69
|
+
await tx.put("schedule", updated, schedule.revision, { parentId: schedule.modelProjectId, status: updated.state });
|
|
70
|
+
return updated;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
// Failed transactions keep the original due time and exact fire identity.
|
|
75
|
+
// A concurrent policy edit owns its new timer; never overwrite that state.
|
|
76
|
+
const failed = attempt;
|
|
77
|
+
if (!failed)
|
|
78
|
+
throw error;
|
|
79
|
+
return repository.transaction(scope, async (tx) => {
|
|
80
|
+
const current = await requireLearningResource(tx, "schedule", scheduleId);
|
|
81
|
+
if (current.revision !== failed.schedule.revision)
|
|
82
|
+
return current;
|
|
83
|
+
const timestamp = now();
|
|
84
|
+
const consecutiveFailures = current.consecutiveFailures + 1;
|
|
85
|
+
const blocked = consecutiveFailures > failed.maxRetries;
|
|
86
|
+
const updated = LearningScheduleSchema.parse({ ...current, revision: current.revision + 1,
|
|
87
|
+
state: blocked ? "blocked" : "scheduled", consecutiveFailures,
|
|
88
|
+
nextAttemptAt: blocked ? null : new Date(Date.parse(timestamp) + Math.min(60_000, 1_000 * 2 ** Math.min(consecutiveFailures - 1, 10))).toISOString(),
|
|
89
|
+
lastError: (error instanceof Error ? error.message : String(error)).slice(0, 20_000), updatedAt: timestamp });
|
|
90
|
+
await tx.put("schedule", updated, current.revision, { parentId: current.modelProjectId, status: updated.state });
|
|
91
|
+
return updated;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return { run };
|
|
96
|
+
}
|
package/dist/learning/service.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { cancelLearningIterationReservation } from "./iteration-reservation-cancellation.js";
|
|
2
2
|
import { commandLearningIterationDispatch } from "./iteration-dispatch-commands.js";
|
|
3
3
|
import { reserveLearningIteration } from "./iteration-reservation-service.js";
|
|
4
|
+
import { synchronizeLearningSchedule } from "./schedule-service.js";
|
|
4
5
|
import { requireCurrentLearningEvidence as currentEvidence, sealLearningBatch } from "./batch-service.js";
|
|
5
6
|
import { saveAuthoringDraft, archiveAuthoringDraft, finalizeAuthoringDraft } from "./authoring-service.js";
|
|
6
7
|
import { queueRewardCheck, cancelRewardCheck } from "./reward-check-service.js";
|
|
@@ -158,6 +159,8 @@ export function createLearningService(repository, options = {}) {
|
|
|
158
159
|
}
|
|
159
160
|
}
|
|
160
161
|
await transaction.put(input.kind, resource, input.expectedRevision, input.kind === "policy" ? { parentId: input.content.modelProjectId } : undefined);
|
|
162
|
+
if (input.kind === "policy")
|
|
163
|
+
await synchronizeLearningSchedule(transaction, LearningPolicySchema.parse(resource), now());
|
|
161
164
|
return pointer(input.kind, resource);
|
|
162
165
|
}
|
|
163
166
|
async function submit(transaction, input) {
|
|
@@ -362,6 +365,10 @@ function authorizeRead(context) {
|
|
|
362
365
|
function authorize(context, input) {
|
|
363
366
|
if (!context.scope.trim() || !context.actor.id.trim())
|
|
364
367
|
throw new LearningDomainError("learning_scope_required", 400);
|
|
368
|
+
const publications = input.action === "publish" ? [input] : input.action === "publish_resources" ? input.resources : [];
|
|
369
|
+
if (context.actor.role !== "reviewer" && publications.some(value => value.kind === "policy" && value.content.enabled
|
|
370
|
+
&& value.content.automation.train && value.content.trigger.kind === "schedule"))
|
|
371
|
+
throw new LearningDomainError("learning_review_not_authorized", 403);
|
|
365
372
|
if (context.actor.role === "source") {
|
|
366
373
|
const sourceId = input.action === "submit_example" ? input.example.sourceId : input.action === "submit_feedback" ? input.feedback.sourceId : null;
|
|
367
374
|
if (!sourceId || sourceId !== context.actor.sourceId)
|
|
@@ -1246,6 +1246,11 @@ export declare const LearningIterationSchema: z.ZodObject<{
|
|
|
1246
1246
|
id: z.ZodString;
|
|
1247
1247
|
contentHash: z.ZodString;
|
|
1248
1248
|
}, z.core.$strict>>;
|
|
1249
|
+
candidateDecision: z.ZodDefault<z.ZodNullable<z.ZodObject<{
|
|
1250
|
+
id: z.ZodString;
|
|
1251
|
+
contentHash: z.ZodString;
|
|
1252
|
+
revision: z.ZodNumber;
|
|
1253
|
+
}, z.core.$strict>>>;
|
|
1249
1254
|
dispatchId: z.ZodString;
|
|
1250
1255
|
retryCount: z.ZodNumber;
|
|
1251
1256
|
spendUsd: z.ZodNumber;
|
|
@@ -2120,6 +2125,11 @@ export declare const LearningResourceSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
2120
2125
|
id: z.ZodString;
|
|
2121
2126
|
contentHash: z.ZodString;
|
|
2122
2127
|
}, z.core.$strict>>;
|
|
2128
|
+
candidateDecision: z.ZodDefault<z.ZodNullable<z.ZodObject<{
|
|
2129
|
+
id: z.ZodString;
|
|
2130
|
+
contentHash: z.ZodString;
|
|
2131
|
+
revision: z.ZodNumber;
|
|
2132
|
+
}, z.core.$strict>>>;
|
|
2123
2133
|
dispatchId: z.ZodString;
|
|
2124
2134
|
retryCount: z.ZodNumber;
|
|
2125
2135
|
spendUsd: z.ZodNumber;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../../../src/learning/contracts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,wBAAwB,2CAAiC,CAAC;AACvE,eAAO,MAAM,yBAAyB;;;;kBAAyB,CAAC;AAChE,eAAO,MAAM,yBAAyB,aAAiJ,CAAC;AAExL,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAsBtC,CAAC;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAsF,CAAC;AAExH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;kBAWzB,CAAC;AACZ;0EAC0E;AAC1E,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;kBAM5B,CAAC;AACZ,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAgBtC,CAAC;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAsF,CAAC;AAExH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAgB7B,CAAC;AAEZ,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAS3B,CAAC;AACZ,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAgF,CAAC;AAEhH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;kBAW9B,CAAC;AACZ,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBASpB,CAAC;AAEZ,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAqB7C,CAAC;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAA6F,CAAC;AAEtI,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAoBjC,CAAC;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAiF,CAAC;AAE9G,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA8BtC,CAAC;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAsF,CAAC;AACxH,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;EAAgO,CAAC;AAC3Q,eAAO,MAAM,uBAAuB
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../../../src/learning/contracts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,wBAAwB,2CAAiC,CAAC;AACvE,eAAO,MAAM,yBAAyB;;;;kBAAyB,CAAC;AAChE,eAAO,MAAM,yBAAyB,aAAiJ,CAAC;AAExL,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAsBtC,CAAC;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAsF,CAAC;AAExH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;kBAWzB,CAAC;AACZ;0EAC0E;AAC1E,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;kBAM5B,CAAC;AACZ,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAgBtC,CAAC;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAsF,CAAC;AAExH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAgB7B,CAAC;AAEZ,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAS3B,CAAC;AACZ,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAgF,CAAC;AAEhH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;kBAW9B,CAAC;AACZ,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBASpB,CAAC;AAEZ,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAqB7C,CAAC;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAA6F,CAAC;AAEtI,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAoBjC,CAAC;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAiF,CAAC;AAE9G,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA8BtC,CAAC;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAsF,CAAC;AACxH,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;EAAgO,CAAC;AAC3Q,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAsBzB,CAAC;AAEZ,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAkBpB,CAAC;AAEZ,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAA2P,CAAC;AAE/R,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAChF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAClF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAChF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AACxD,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACxE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACtE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,wBAAgB,WAAW,CAAC,QAAQ,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,mBAAmB,CAEhH;AACD,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAE9F;AACD,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAG9G;AACD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAIjF"}
|
|
@@ -15,4 +15,8 @@ export * from "./reward-fixture-executor.js";
|
|
|
15
15
|
export * from "./iteration-reservation-contracts.js";
|
|
16
16
|
export * from "./iteration-dispatch-contracts.js";
|
|
17
17
|
export * from "./iteration-dispatch-worker.js";
|
|
18
|
+
export * from "./iteration-candidate-decision.js";
|
|
19
|
+
export * from "./schedule-contracts.js";
|
|
20
|
+
export * from "./schedule-service.js";
|
|
21
|
+
export * from "./schedule-worker.js";
|
|
18
22
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/learning/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/learning/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mCAAmC,CAAC;AAClD,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type LearningRepository } from "./repository.js";
|
|
3
|
+
export declare const LearningCandidateDecisionObservationSchema: z.ZodObject<{
|
|
4
|
+
scope: z.ZodString;
|
|
5
|
+
iterationId: z.ZodString;
|
|
6
|
+
decision: z.ZodObject<{
|
|
7
|
+
id: z.ZodString;
|
|
8
|
+
contentHash: z.ZodString;
|
|
9
|
+
revision: z.ZodNumber;
|
|
10
|
+
}, z.core.$strict>;
|
|
11
|
+
outcome: z.ZodEnum<{
|
|
12
|
+
rejected: "rejected";
|
|
13
|
+
accepted: "accepted";
|
|
14
|
+
}>;
|
|
15
|
+
execution: z.ZodObject<{
|
|
16
|
+
id: z.ZodString;
|
|
17
|
+
contentHash: z.ZodString;
|
|
18
|
+
}, z.core.$strict>;
|
|
19
|
+
candidate: z.ZodObject<{
|
|
20
|
+
id: z.ZodString;
|
|
21
|
+
contentHash: z.ZodString;
|
|
22
|
+
}, z.core.$strict>;
|
|
23
|
+
evaluation: z.ZodObject<{
|
|
24
|
+
id: z.ZodString;
|
|
25
|
+
contentHash: z.ZodString;
|
|
26
|
+
}, z.core.$strict>;
|
|
27
|
+
receipt: z.ZodObject<{
|
|
28
|
+
id: z.ZodString;
|
|
29
|
+
contentHash: z.ZodString;
|
|
30
|
+
}, z.core.$strict>;
|
|
31
|
+
}, z.core.$strict>;
|
|
32
|
+
export type LearningCandidateDecisionObservation = z.infer<typeof LearningCandidateDecisionObservationSchema>;
|
|
33
|
+
/** Trusted host boundary: verify the provider's immutable decision and ownership
|
|
34
|
+
* before calling. This reconciles retained evidence; it does not authorize a
|
|
35
|
+
* review, accept a model automatically, or activate serving. */
|
|
36
|
+
export declare function reconcileLearningCandidateDecision(repository: LearningRepository, value: LearningCandidateDecisionObservation, options?: {
|
|
37
|
+
now?: () => string;
|
|
38
|
+
}): Promise<{
|
|
39
|
+
schemaVersion: "openpond.learningIteration.v1";
|
|
40
|
+
id: string;
|
|
41
|
+
revision: number;
|
|
42
|
+
policy: {
|
|
43
|
+
id: string;
|
|
44
|
+
contentHash: string;
|
|
45
|
+
revision: number;
|
|
46
|
+
};
|
|
47
|
+
status: "failed" | "cancelled" | "rejected" | "accepted" | "training" | "waiting_for_data" | "waiting_for_review" | "ready" | "dispatching" | "evaluating" | "candidate_ready" | "paused" | "cancelling" | "completed_without_candidate";
|
|
48
|
+
triggerIdentity: string;
|
|
49
|
+
batch: {
|
|
50
|
+
id: string;
|
|
51
|
+
contentHash: string;
|
|
52
|
+
revision: number;
|
|
53
|
+
} | null;
|
|
54
|
+
sourceWatermarks: Record<string, number>;
|
|
55
|
+
trainingParent: {
|
|
56
|
+
id: string;
|
|
57
|
+
contentHash: string;
|
|
58
|
+
};
|
|
59
|
+
teacher: {
|
|
60
|
+
id: string;
|
|
61
|
+
contentHash: string;
|
|
62
|
+
} | null;
|
|
63
|
+
upstreamEvent: {
|
|
64
|
+
id: string;
|
|
65
|
+
contentHash: string;
|
|
66
|
+
} | null;
|
|
67
|
+
trainingJob: {
|
|
68
|
+
id: string;
|
|
69
|
+
contentHash: string;
|
|
70
|
+
} | null;
|
|
71
|
+
evaluationJob: {
|
|
72
|
+
id: string;
|
|
73
|
+
contentHash: string;
|
|
74
|
+
} | null;
|
|
75
|
+
candidateVersion: {
|
|
76
|
+
id: string;
|
|
77
|
+
contentHash: string;
|
|
78
|
+
} | null;
|
|
79
|
+
candidateDecision: {
|
|
80
|
+
id: string;
|
|
81
|
+
contentHash: string;
|
|
82
|
+
revision: number;
|
|
83
|
+
} | null;
|
|
84
|
+
dispatchId: string;
|
|
85
|
+
retryCount: number;
|
|
86
|
+
spendUsd: number;
|
|
87
|
+
failure: {
|
|
88
|
+
code: string;
|
|
89
|
+
message: string;
|
|
90
|
+
} | null;
|
|
91
|
+
createdAt: string;
|
|
92
|
+
updatedAt: string;
|
|
93
|
+
}>;
|
|
94
|
+
//# sourceMappingURL=iteration-candidate-decision.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iteration-candidate-decision.d.ts","sourceRoot":"","sources":["../../../../../src/learning/iteration-candidate-decision.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,EAA2B,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEnF,eAAO,MAAM,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAS5C,CAAC;AACZ,MAAM,MAAM,oCAAoC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0CAA0C,CAAC,CAAC;AAE9G;;gEAEgE;AAChE,wBAAsB,kCAAkC,CAAC,UAAU,EAAE,kBAAkB,EAAE,KAAK,EAAE,oCAAoC,EAClI,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BrC"}
|
|
@@ -1152,6 +1152,69 @@ export declare const learningResourceSchemas: {
|
|
|
1152
1152
|
createdAt: z.ZodString;
|
|
1153
1153
|
updatedAt: z.ZodString;
|
|
1154
1154
|
}, z.core.$strict>;
|
|
1155
|
+
readonly schedule: z.ZodObject<{
|
|
1156
|
+
schemaVersion: z.ZodLiteral<"openpond.learningSchedule.v1">;
|
|
1157
|
+
id: z.ZodString;
|
|
1158
|
+
revision: z.ZodNumber;
|
|
1159
|
+
policy: z.ZodObject<{
|
|
1160
|
+
id: z.ZodString;
|
|
1161
|
+
contentHash: z.ZodString;
|
|
1162
|
+
revision: z.ZodNumber;
|
|
1163
|
+
}, z.core.$strict>;
|
|
1164
|
+
modelProjectId: z.ZodString;
|
|
1165
|
+
executionOwner: z.ZodEnum<{
|
|
1166
|
+
local: "local";
|
|
1167
|
+
hosted: "hosted";
|
|
1168
|
+
}>;
|
|
1169
|
+
state: z.ZodEnum<{
|
|
1170
|
+
blocked: "blocked";
|
|
1171
|
+
scheduled: "scheduled";
|
|
1172
|
+
disabled: "disabled";
|
|
1173
|
+
}>;
|
|
1174
|
+
intervalSeconds: z.ZodNullable<z.ZodNumber>;
|
|
1175
|
+
nextRunAt: z.ZodNullable<z.ZodString>;
|
|
1176
|
+
lastFire: z.ZodNullable<z.ZodObject<{
|
|
1177
|
+
id: z.ZodString;
|
|
1178
|
+
contentHash: z.ZodString;
|
|
1179
|
+
revision: z.ZodNumber;
|
|
1180
|
+
}, z.core.$strict>>;
|
|
1181
|
+
consecutiveFailures: z.ZodNumber;
|
|
1182
|
+
nextAttemptAt: z.ZodNullable<z.ZodString>;
|
|
1183
|
+
lastError: z.ZodNullable<z.ZodString>;
|
|
1184
|
+
createdAt: z.ZodString;
|
|
1185
|
+
updatedAt: z.ZodString;
|
|
1186
|
+
}, z.core.$strict>;
|
|
1187
|
+
readonly schedule_fire: z.ZodObject<{
|
|
1188
|
+
schemaVersion: z.ZodLiteral<"openpond.learningScheduleFire.v1">;
|
|
1189
|
+
id: z.ZodString;
|
|
1190
|
+
revision: z.ZodLiteral<1>;
|
|
1191
|
+
scheduleId: z.ZodString;
|
|
1192
|
+
policy: z.ZodObject<{
|
|
1193
|
+
id: z.ZodString;
|
|
1194
|
+
contentHash: z.ZodString;
|
|
1195
|
+
revision: z.ZodNumber;
|
|
1196
|
+
}, z.core.$strict>;
|
|
1197
|
+
scheduledAt: z.ZodString;
|
|
1198
|
+
coalescedThroughAt: z.ZodString;
|
|
1199
|
+
coalescedCount: z.ZodNumber;
|
|
1200
|
+
outcome: z.ZodEnum<{
|
|
1201
|
+
skipped: "skipped";
|
|
1202
|
+
waiting_for_data: "waiting_for_data";
|
|
1203
|
+
waiting_for_review: "waiting_for_review";
|
|
1204
|
+
reserved: "reserved";
|
|
1205
|
+
}>;
|
|
1206
|
+
reason: z.ZodNullable<z.ZodEnum<{
|
|
1207
|
+
active_iteration: "active_iteration";
|
|
1208
|
+
cooldown: "cooldown";
|
|
1209
|
+
daily_budget: "daily_budget";
|
|
1210
|
+
}>>;
|
|
1211
|
+
iteration: z.ZodNullable<z.ZodObject<{
|
|
1212
|
+
id: z.ZodString;
|
|
1213
|
+
revision: z.ZodNumber;
|
|
1214
|
+
}, z.core.$strict>>;
|
|
1215
|
+
createdAt: z.ZodString;
|
|
1216
|
+
contentHash: z.ZodString;
|
|
1217
|
+
}, z.core.$strict>;
|
|
1155
1218
|
readonly iteration: z.ZodObject<{
|
|
1156
1219
|
schemaVersion: z.ZodLiteral<"openpond.learningIteration.v1">;
|
|
1157
1220
|
id: z.ZodString;
|
|
@@ -1208,6 +1271,11 @@ export declare const learningResourceSchemas: {
|
|
|
1208
1271
|
id: z.ZodString;
|
|
1209
1272
|
contentHash: z.ZodString;
|
|
1210
1273
|
}, z.core.$strict>>;
|
|
1274
|
+
candidateDecision: z.ZodDefault<z.ZodNullable<z.ZodObject<{
|
|
1275
|
+
id: z.ZodString;
|
|
1276
|
+
contentHash: z.ZodString;
|
|
1277
|
+
revision: z.ZodNumber;
|
|
1278
|
+
}, z.core.$strict>>>;
|
|
1211
1279
|
dispatchId: z.ZodString;
|
|
1212
1280
|
retryCount: z.ZodNumber;
|
|
1213
1281
|
spendUsd: z.ZodNumber;
|
|
@@ -1545,14 +1613,16 @@ export declare const LearningResourceKindSchema: z.ZodEnum<{
|
|
|
1545
1613
|
binding: "binding";
|
|
1546
1614
|
batch: "batch";
|
|
1547
1615
|
grade: "grade";
|
|
1616
|
+
schedule: "schedule";
|
|
1548
1617
|
definition: "definition";
|
|
1549
1618
|
draft: "draft";
|
|
1619
|
+
iteration: "iteration";
|
|
1550
1620
|
reward_check: "reward_check";
|
|
1551
1621
|
chain: "chain";
|
|
1552
1622
|
consumption: "consumption";
|
|
1553
1623
|
reservation: "reservation";
|
|
1554
1624
|
dispatch: "dispatch";
|
|
1555
|
-
|
|
1625
|
+
schedule_fire: "schedule_fire";
|
|
1556
1626
|
package: "package";
|
|
1557
1627
|
}>;
|
|
1558
1628
|
export type LearningResourceFor<K extends LearningResourceKind> = z.infer<(typeof learningResourceSchemas)[K]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../../../src/learning/repository.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../../../src/learning/repository.ts"],"names":[],"mappings":"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"}
|