@treeseed/sdk 0.13.0-rc.118 → 0.13.0-rc.119

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 (73) hide show
  1. package/dist/.treeseed-build-complete.json +1 -1
  2. package/dist/agent-capacity/contracts/capacity/assignments/agent-execution.d.ts +4199 -0
  3. package/dist/agent-capacity/contracts/capacity/assignments/agent-execution.js +155 -0
  4. package/dist/agent-capacity/contracts/capacity/assignments/assignment-records.d.ts +7 -1
  5. package/dist/agent-capacity/contracts/capacity/workdays/workday-allocation.d.ts +199 -0
  6. package/dist/agent-capacity/contracts/capacity/workdays/workday-allocation.js +96 -0
  7. package/dist/agent-capacity/contracts/operations/agent-team-clone.d.ts +218 -0
  8. package/dist/agent-capacity/contracts/operations/agent-team-clone.js +57 -0
  9. package/dist/agent-capacity/contracts/support/decision-work.d.ts +1 -24
  10. package/dist/agent-capacity/contracts/support/execution-graph.d.ts +1087 -0
  11. package/dist/agent-capacity/contracts/support/execution-graph.js +120 -0
  12. package/dist/agent-capacity/validation/activity-profile.d.ts +1 -1
  13. package/dist/agent-capacity/validation/activity-profile.js +3 -272
  14. package/dist/agent-capacity/validation/agent-definition-schema.d.ts +2699 -8867
  15. package/dist/agent-capacity/validation/agent-definition-schema.js +67 -159
  16. package/dist/agent-capacity/validation/agent-lab-forensics-schema.d.ts +3 -3
  17. package/dist/agent-capacity/validation/assignment-records.js +1 -1
  18. package/dist/agent-capacity/validation/execution/execution-graph.d.ts +1 -0
  19. package/dist/agent-capacity/validation/execution/execution-graph.js +16 -0
  20. package/dist/agent-capacity/validation/index.d.ts +2 -1
  21. package/dist/agent-capacity/validation/index.js +2 -1
  22. package/dist/capacity/agents/agent-capacity.d.ts +5 -1
  23. package/dist/capacity/agents/agent-capacity.js +4 -1
  24. package/dist/capacity-provider/client.d.ts +1 -43
  25. package/dist/capacity-provider/client.js +1 -22
  26. package/dist/capacity-provider/sandbox-contracts.d.ts +4 -4
  27. package/dist/capacity-provider/sandbox.d.ts +0 -1
  28. package/dist/capacity-provider/sandbox.js +0 -1
  29. package/dist/capacity-provider/source-workspace.d.ts +19 -171
  30. package/dist/capacity-provider/source-workspace.js +7 -24
  31. package/dist/content/contracts.d.ts +1 -1
  32. package/dist/content/validation/agent-operational-content-schemas.d.ts +24 -695
  33. package/dist/content/validation/agent-operational-content-schemas.js +11 -54
  34. package/dist/content/validation/auxiliary-content-schemas.d.ts +58 -58
  35. package/dist/content/validation/content-model-schemas.d.ts +8617 -18610
  36. package/dist/content/validation/content-model-schemas.js +160 -43
  37. package/dist/content/validation/portable-content-data.d.ts +369 -1681
  38. package/dist/content/validation/portable-content-data.js +5 -4
  39. package/dist/model-registry/agent-operational-models.d.ts +1 -1
  40. package/dist/model-registry/agent-operational-models.js +0 -3
  41. package/dist/model-registry/build-builtin-model-registry.js +44 -72
  42. package/dist/operator-contracts/canonical-command-tree.js +62 -179
  43. package/dist/operator-contracts/catalog/agents/agent-team-clone-operations.d.ts +75 -0
  44. package/dist/operator-contracts/catalog/agents/agent-team-clone-operations.js +42 -0
  45. package/dist/operator-contracts/catalog/commands/command-tree-builders.d.ts +60 -0
  46. package/dist/operator-contracts/catalog/commands/command-tree-builders.js +191 -0
  47. package/dist/operator-contracts/catalog/communication-operations.d.ts +1 -1
  48. package/dist/operator-contracts/catalog/execution/execution-operations.d.ts +36 -0
  49. package/dist/operator-contracts/catalog/execution/execution-operations.js +39 -0
  50. package/dist/operator-contracts/catalog/inbox-operations.d.ts +5 -1
  51. package/dist/operator-contracts/command-tree.js +1 -0
  52. package/dist/operator-contracts/control-plane-operations.d.ts +136 -73
  53. package/dist/operator-contracts/control-plane-operations.js +19 -40
  54. package/dist/operator-contracts/inbox/contracts.d.ts +12 -0
  55. package/dist/operator-contracts/inbox/contracts.js +5 -1
  56. package/dist/operator-contracts/mcp.js +1 -1
  57. package/dist/operator-contracts/workday-lifecycle.d.ts +6 -8
  58. package/dist/operator-contracts/workday-lifecycle.js +3 -3
  59. package/dist/sdk-types/support/sdk-model-names.d.ts +1 -1
  60. package/dist/sdk-types/support/sdk-model-names.js +0 -3
  61. package/dist/secrets-capability/shared-resources.d.ts +6 -6
  62. package/dist/types/agents/agent-activity-profile.d.ts +39 -77
  63. package/dist/types/agents/agent-activity-profile.js +23 -0
  64. package/dist/types/agents/execution-run-ref.d.ts +1 -8
  65. package/package.json +1 -1
  66. package/dist/agent-capacity/authority/agent-authority-presets.d.ts +0 -13
  67. package/dist/agent-capacity/authority/agent-authority-presets.js +0 -107
  68. package/dist/agent-capacity/contracts/operations/workflow-promotion.d.ts +0 -24
  69. package/dist/agent-capacity/contracts/operations/workflow-promotion.js +0 -0
  70. package/dist/agent-capacity/validation/workflow-promotion.d.ts +0 -2
  71. package/dist/agent-capacity/validation/workflow-promotion.js +0 -34
  72. package/dist/capacity-provider/source/candidate.d.ts +0 -1275
  73. package/dist/capacity-provider/source/candidate.js +0 -72
@@ -0,0 +1,155 @@
1
+ import { z } from "zod";
2
+ import { activityProfileSchema } from "../../../validation/agent-definition-schema.js";
3
+ const identifier = z.string().trim().min(1).max(200).regex(/^[A-Za-z0-9][A-Za-z0-9._:/-]*$/u);
4
+ const timestamp = z.string().datetime({ offset: true });
5
+ const digest = z.string().regex(/^sha256:[a-f0-9]{64}$/u);
6
+ const commit = z.string().regex(/^[a-f0-9]{40}$/u);
7
+ const uniqueStrings = z.array(z.string().min(1)).superRefine((items, context) => {
8
+ if (new Set(items).size !== items.length) context.addIssue({ code: z.ZodIssueCode.custom, message: "Values must be unique." });
9
+ });
10
+ const exactEntityReferenceSchema = z.object({
11
+ store: z.enum(["treedx", "postgresql", "git", "url"]),
12
+ model: z.string().min(1),
13
+ id: identifier,
14
+ revision: z.number().int().positive().optional(),
15
+ digest: digest.optional(),
16
+ repository: z.string().min(1).optional(),
17
+ commit: commit.optional(),
18
+ path: z.string().min(1).optional(),
19
+ anchor: z.string().min(1).optional(),
20
+ startLine: z.number().int().positive().optional(),
21
+ endLine: z.number().int().positive().optional(),
22
+ url: z.string().url().optional()
23
+ }).strict().superRefine((reference, context) => {
24
+ if (reference.endLine && !reference.startLine) context.addIssue({ code: z.ZodIssueCode.custom, path: ["startLine"], message: "startLine is required with endLine." });
25
+ if (reference.store === "treedx" && !(reference.commit || reference.revision && reference.digest)) context.addIssue({ code: z.ZodIssueCode.custom, message: "TreeDX references require commit or revision and digest." });
26
+ if (reference.store === "git" && !(reference.repository && reference.commit)) context.addIssue({ code: z.ZodIssueCode.custom, message: "Git references require repository and commit." });
27
+ if (reference.store === "url" && !reference.url) context.addIssue({ code: z.ZodIssueCode.custom, message: "URL references require url." });
28
+ });
29
+ const assignmentReferenceSchema = z.discriminatedUnion("kind", [
30
+ z.object({ kind: z.literal("git"), repository: z.string().min(1), commit, branch: z.string().min(1).optional(), path: z.string().min(1).optional() }).strict(),
31
+ z.object({ kind: z.literal("treedx"), projectId: identifier, repository: z.string().min(1), commit, path: z.string().min(1), workspaceId: identifier.optional() }).strict(),
32
+ z.object({ kind: z.literal("url"), url: z.string().url(), digest: digest.optional() }).strict()
33
+ ]);
34
+ const exactGrantSchema = z.object({
35
+ contentRead: z.array(exactEntityReferenceSchema),
36
+ contentWrite: z.array(exactEntityReferenceSchema),
37
+ sourceRead: uniqueStrings,
38
+ sourceWrite: uniqueStrings,
39
+ tools: uniqueStrings
40
+ }).strict();
41
+ const assignmentWorkspaceSchema = z.discriminatedUnion("mode", [
42
+ z.object({ mode: z.literal("read-only") }).strict(),
43
+ z.object({ mode: z.literal("treedx"), workspaceId: identifier, repository: z.string().min(1), baseCommit: commit, writablePaths: uniqueStrings.refine((paths) => paths.length > 0) }).strict(),
44
+ z.object({ mode: z.literal("git"), repository: z.string().min(1), baseCommit: commit, branch: z.string().min(1), writablePaths: uniqueStrings.refine((paths) => paths.length > 0) }).strict()
45
+ ]);
46
+ const estimateSchema = z.object({
47
+ minimumSeconds: z.number().int().positive(),
48
+ expectedSeconds: z.number().int().positive(),
49
+ maximumSeconds: z.number().int().positive(),
50
+ rationale: z.string().optional()
51
+ }).strict().refine((value) => value.minimumSeconds <= value.expectedSeconds && value.expectedSeconds <= value.maximumSeconds, {
52
+ message: "Estimate must satisfy minimumSeconds <= expectedSeconds <= maximumSeconds."
53
+ });
54
+ const effectiveActivityProfileSchema = activityProfileSchema.omit({ dependsOn: true }).extend({
55
+ profileRef: exactEntityReferenceSchema,
56
+ activity: z.enum(["planning", "estimating", "acting", "reviewing", "reporting", "chat"]),
57
+ handlerOrigin: z.enum(["agent-package", "project-runtime"]),
58
+ permissionCeiling: activityProfileSchema.shape.permissions
59
+ }).omit({ permissions: true }).strict();
60
+ const providerSelectionSchema = z.object({ providerId: identifier, offerId: identifier, offerRevision: z.number().int().positive(), runtimeBuild: digest }).strict();
61
+ const limitsSchema = z.object({
62
+ maximumSeconds: z.number().int().positive(),
63
+ maximumContextBytes: z.number().int().positive(),
64
+ maximumContextTokens: z.number().int().positive().optional(),
65
+ maximumContextItems: z.number().int().positive()
66
+ }).strict();
67
+ const assignmentAttemptSchema = z.object({
68
+ schemaVersion: z.literal("treeseed.assignment-attempt/v1"),
69
+ id: identifier,
70
+ idempotencyKey: identifier,
71
+ teamId: identifier,
72
+ projectId: identifier,
73
+ workdayId: identifier,
74
+ nodeId: identifier,
75
+ workItemId: identifier.optional(),
76
+ nodeRevision: z.number().int().positive(),
77
+ graphRevision: z.number().int().positive(),
78
+ sourceRef: exactEntityReferenceSchema,
79
+ authorityRefs: z.array(exactEntityReferenceSchema).min(1),
80
+ effectiveProfile: effectiveActivityProfileSchema,
81
+ requiredCapabilities: uniqueStrings,
82
+ grant: exactGrantSchema,
83
+ provider: providerSelectionSchema,
84
+ contextRefs: z.array(exactEntityReferenceSchema),
85
+ predecessorResultIds: uniqueStrings,
86
+ acceptanceCriteria: z.array(z.string().trim().min(1)).min(1).optional(),
87
+ workspace: assignmentWorkspaceSchema,
88
+ estimate: estimateSchema,
89
+ limits: limitsSchema,
90
+ deadline: timestamp,
91
+ leaseId: identifier,
92
+ reservationId: identifier,
93
+ attempt: z.number().int().positive(),
94
+ status: z.enum(["created", "leased", "running", "completed", "blocked", "failed", "cancelled", "expired"]),
95
+ createdAt: timestamp,
96
+ startedAt: timestamp.optional(),
97
+ finishedAt: timestamp.optional()
98
+ }).strict();
99
+ const verificationRecordSchema = z.object({
100
+ command: z.string().min(1),
101
+ status: z.enum(["passed", "failed", "skipped"]),
102
+ exitCode: z.number().int(),
103
+ outputDigest: digest,
104
+ durationSeconds: z.number().int().nonnegative().optional()
105
+ }).strict();
106
+ const usageSchema = z.object({
107
+ elapsedSeconds: z.number().int().nonnegative(),
108
+ modelInputTokens: z.number().int().nonnegative().optional(),
109
+ modelOutputTokens: z.number().int().nonnegative().optional(),
110
+ native: z.record(z.number().nonnegative()).optional()
111
+ }).strict();
112
+ const diagnosticSchema = z.object({
113
+ code: identifier,
114
+ severity: z.enum(["info", "warning", "error"]),
115
+ message: z.string().min(1),
116
+ ref: exactEntityReferenceSchema.optional()
117
+ }).strict();
118
+ const assignmentResultSchema = z.object({
119
+ schemaVersion: z.literal("treeseed.assignment-result/v1"),
120
+ id: identifier,
121
+ assignmentId: identifier,
122
+ status: z.enum(["completed", "blocked", "failed"]),
123
+ summary: z.string().min(1),
124
+ references: z.array(assignmentReferenceSchema),
125
+ verification: z.array(verificationRecordSchema),
126
+ usage: usageSchema,
127
+ diagnostics: z.array(diagnosticSchema),
128
+ completedAt: timestamp
129
+ }).strict();
130
+ const authorizedContextItemSchema = z.object({
131
+ ref: exactEntityReferenceSchema,
132
+ mediaType: z.string().min(1),
133
+ digest,
134
+ value: z.any()
135
+ }).strict();
136
+ const assignmentContextSchema = z.object({
137
+ assignment: assignmentAttemptSchema,
138
+ context: z.array(authorizedContextItemSchema),
139
+ predecessorResults: z.array(assignmentResultSchema)
140
+ }).strict();
141
+ export {
142
+ assignmentAttemptSchema,
143
+ assignmentContextSchema,
144
+ assignmentReferenceSchema,
145
+ assignmentResultSchema,
146
+ assignmentWorkspaceSchema,
147
+ authorizedContextItemSchema,
148
+ diagnosticSchema,
149
+ effectiveActivityProfileSchema,
150
+ estimateSchema,
151
+ exactEntityReferenceSchema,
152
+ exactGrantSchema,
153
+ usageSchema,
154
+ verificationRecordSchema
155
+ };
@@ -3,7 +3,7 @@ import type { AgentWorkExecutionMode } from '../../support/authority/execution-m
3
3
  export type ProviderAssignmentStatus = 'pending' | 'leased' | 'running' | 'completed' | 'failed' | 'returned' | 'expired' | 'cancelled';
4
4
  export type ProviderAssignmentLeaseState = 'unleased' | 'leased' | 'released' | 'expired';
5
5
  export type AgentModeRunStatus = 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled';
6
- export type ProviderAssignmentSynthesisSource = 'approved_decision' | 'planning_input_request' | 'capacity_plan' | 'workday_demand' | 'verification_failure' | 'fallback_queue';
6
+ export type ProviderAssignmentSynthesisSource = 'approved_decision' | 'planning_input_request' | 'capacity_plan' | 'living_execution_graph' | 'workday_demand' | 'verification_failure' | 'fallback_queue';
7
7
  export declare const AGENT_ASSIGNMENT_WORKSPACE_ACCESS_MODES: readonly ["context_only", "workspace_write", "brokered_workspace", "full_workspace_no_credentials", "trusted_direct"];
8
8
  export type AgentAssignmentWorkspaceAccessMode = (typeof AGENT_ASSIGNMENT_WORKSPACE_ACCESS_MODES)[number];
9
9
  export type AgentAssignmentCapabilityHandleKind = 'repository_access' | 'treedx_workspace' | 'workflow_operation' | 'secret_use';
@@ -59,6 +59,7 @@ export interface TreeDxProxyHandle {
59
59
  assignmentId?: string | null;
60
60
  executionMode?: AgentWorkExecutionMode;
61
61
  repositoryId?: string | null;
62
+ repositoryProjectId?: string | null;
62
63
  workspaceId?: string | null;
63
64
  baseCommitSha?: string | null;
64
65
  baseRef?: string | null;
@@ -198,6 +199,11 @@ export interface ProviderAssignment {
198
199
  synthesisKey: string | null;
199
200
  decisionId: string | null;
200
201
  proposalId: string | null;
202
+ graphRevision?: number | null;
203
+ executionNodeId?: string | null;
204
+ executionNodeRevision?: number | null;
205
+ assignmentAttempt?: import('./agent-execution.js').AssignmentAttempt | null;
206
+ assignmentResult?: import('./agent-execution.js').AssignmentResult | null;
201
207
  fallbackOutputId: string | null;
202
208
  treedxProxyHandle: TreeDxProxyHandle | Record<string, unknown> | null;
203
209
  capabilityHandles: ProviderAssignmentCapabilityHandles | Record<string, unknown> | null;
@@ -0,0 +1,199 @@
1
+ import { z } from 'zod';
2
+ export declare const workdayPolicySchema: z.ZodObject<{
3
+ durationSeconds: z.ZodNumber;
4
+ maximumConcurrency: z.ZodNumber;
5
+ planningSecondsPerAgent: z.ZodNumber;
6
+ communicationConcurrency: z.ZodNumber;
7
+ projectWeights: z.ZodRecord<z.ZodString, z.ZodNumber>;
8
+ agentClassWeights: z.ZodRecord<z.ZodString, z.ZodNumber>;
9
+ }, "strict", z.ZodTypeAny, {
10
+ durationSeconds: number;
11
+ maximumConcurrency: number;
12
+ planningSecondsPerAgent: number;
13
+ communicationConcurrency: number;
14
+ projectWeights: Record<string, number>;
15
+ agentClassWeights: Record<string, number>;
16
+ }, {
17
+ durationSeconds: number;
18
+ maximumConcurrency: number;
19
+ planningSecondsPerAgent: number;
20
+ communicationConcurrency: number;
21
+ projectWeights: Record<string, number>;
22
+ agentClassWeights: Record<string, number>;
23
+ }>;
24
+ export declare const appliedWorkdaySchema: z.ZodObject<{
25
+ schemaVersion: z.ZodLiteral<"treeseed.workday/v1">;
26
+ id: z.ZodString;
27
+ teamId: z.ZodString;
28
+ policyId: z.ZodString;
29
+ policyRevision: z.ZodNumber;
30
+ policySnapshot: z.ZodObject<{
31
+ durationSeconds: z.ZodNumber;
32
+ maximumConcurrency: z.ZodNumber;
33
+ planningSecondsPerAgent: z.ZodNumber;
34
+ communicationConcurrency: z.ZodNumber;
35
+ projectWeights: z.ZodRecord<z.ZodString, z.ZodNumber>;
36
+ agentClassWeights: z.ZodRecord<z.ZodString, z.ZodNumber>;
37
+ }, "strict", z.ZodTypeAny, {
38
+ durationSeconds: number;
39
+ maximumConcurrency: number;
40
+ planningSecondsPerAgent: number;
41
+ communicationConcurrency: number;
42
+ projectWeights: Record<string, number>;
43
+ agentClassWeights: Record<string, number>;
44
+ }, {
45
+ durationSeconds: number;
46
+ maximumConcurrency: number;
47
+ planningSecondsPerAgent: number;
48
+ communicationConcurrency: number;
49
+ projectWeights: Record<string, number>;
50
+ agentClassWeights: Record<string, number>;
51
+ }>;
52
+ state: z.ZodEnum<["planned", "active", "closing", "ended"]>;
53
+ startsAt: z.ZodString;
54
+ endsAt: z.ZodString;
55
+ planningRounds: z.ZodArray<z.ZodObject<{
56
+ round: z.ZodUnion<[z.ZodLiteral<1>, z.ZodLiteral<2>]>;
57
+ state: z.ZodEnum<["pending", "active", "complete"]>;
58
+ assignmentIds: z.ZodArray<z.ZodString, "many">;
59
+ startedAt: z.ZodOptional<z.ZodString>;
60
+ completedAt: z.ZodOptional<z.ZodString>;
61
+ }, "strict", z.ZodTypeAny, {
62
+ state: "active" | "pending" | "complete";
63
+ round: 1 | 2;
64
+ assignmentIds: string[];
65
+ completedAt?: string | undefined;
66
+ startedAt?: string | undefined;
67
+ }, {
68
+ state: "active" | "pending" | "complete";
69
+ round: 1 | 2;
70
+ assignmentIds: string[];
71
+ completedAt?: string | undefined;
72
+ startedAt?: string | undefined;
73
+ }>, "many">;
74
+ admittedSecondsByProject: z.ZodRecord<z.ZodString, z.ZodNumber>;
75
+ admittedSecondsByAgentClass: z.ZodRecord<z.ZodString, z.ZodNumber>;
76
+ activatedAt: z.ZodOptional<z.ZodString>;
77
+ closingAt: z.ZodOptional<z.ZodString>;
78
+ endedAt: z.ZodOptional<z.ZodString>;
79
+ }, "strict", z.ZodTypeAny, {
80
+ id: string;
81
+ state: "active" | "planned" | "closing" | "ended";
82
+ schemaVersion: "treeseed.workday/v1";
83
+ teamId: string;
84
+ startsAt: string;
85
+ endsAt: string;
86
+ policyId: string;
87
+ policyRevision: number;
88
+ policySnapshot: {
89
+ durationSeconds: number;
90
+ maximumConcurrency: number;
91
+ planningSecondsPerAgent: number;
92
+ communicationConcurrency: number;
93
+ projectWeights: Record<string, number>;
94
+ agentClassWeights: Record<string, number>;
95
+ };
96
+ planningRounds: {
97
+ state: "active" | "pending" | "complete";
98
+ round: 1 | 2;
99
+ assignmentIds: string[];
100
+ completedAt?: string | undefined;
101
+ startedAt?: string | undefined;
102
+ }[];
103
+ admittedSecondsByProject: Record<string, number>;
104
+ admittedSecondsByAgentClass: Record<string, number>;
105
+ activatedAt?: string | undefined;
106
+ closingAt?: string | undefined;
107
+ endedAt?: string | undefined;
108
+ }, {
109
+ id: string;
110
+ state: "active" | "planned" | "closing" | "ended";
111
+ schemaVersion: "treeseed.workday/v1";
112
+ teamId: string;
113
+ startsAt: string;
114
+ endsAt: string;
115
+ policyId: string;
116
+ policyRevision: number;
117
+ policySnapshot: {
118
+ durationSeconds: number;
119
+ maximumConcurrency: number;
120
+ planningSecondsPerAgent: number;
121
+ communicationConcurrency: number;
122
+ projectWeights: Record<string, number>;
123
+ agentClassWeights: Record<string, number>;
124
+ };
125
+ planningRounds: {
126
+ state: "active" | "pending" | "complete";
127
+ round: 1 | 2;
128
+ assignmentIds: string[];
129
+ completedAt?: string | undefined;
130
+ startedAt?: string | undefined;
131
+ }[];
132
+ admittedSecondsByProject: Record<string, number>;
133
+ admittedSecondsByAgentClass: Record<string, number>;
134
+ activatedAt?: string | undefined;
135
+ closingAt?: string | undefined;
136
+ endedAt?: string | undefined;
137
+ }>;
138
+ export interface FairReadyNode {
139
+ id: string;
140
+ projectId: string;
141
+ agentClass: string;
142
+ graphPriority: number;
143
+ readyAt: string;
144
+ }
145
+ export interface FairUsage {
146
+ projectId: string;
147
+ agentClass: string;
148
+ seconds: number;
149
+ }
150
+ /** Select work only; provider selection is a later hard-gated admission step. */
151
+ export declare function selectFairReadyNode(nodes: FairReadyNode[], usage: FairUsage[], policy: z.infer<typeof workdayPolicySchema>): FairReadyNode | null;
152
+ export declare function compilePlanningRounds(workdayId: string, agentIds: string[], planningSecondsPerAgent: number): {
153
+ id: string;
154
+ agentId: string;
155
+ round: number;
156
+ maximumSeconds: number;
157
+ dependsOn: string[];
158
+ }[];
159
+ /** Shared by read-only plan and mutating start; callers persist this exact value. */
160
+ export declare function compileWorkday(input: {
161
+ id: string;
162
+ teamId: string;
163
+ policyId: string;
164
+ policyRevision: number;
165
+ policy: z.input<typeof workdayPolicySchema>;
166
+ agentIds: string[];
167
+ startsAt: string;
168
+ }): {
169
+ id: string;
170
+ state: "active" | "planned" | "closing" | "ended";
171
+ schemaVersion: "treeseed.workday/v1";
172
+ teamId: string;
173
+ startsAt: string;
174
+ endsAt: string;
175
+ policyId: string;
176
+ policyRevision: number;
177
+ policySnapshot: {
178
+ durationSeconds: number;
179
+ maximumConcurrency: number;
180
+ planningSecondsPerAgent: number;
181
+ communicationConcurrency: number;
182
+ projectWeights: Record<string, number>;
183
+ agentClassWeights: Record<string, number>;
184
+ };
185
+ planningRounds: {
186
+ state: "active" | "pending" | "complete";
187
+ round: 1 | 2;
188
+ assignmentIds: string[];
189
+ completedAt?: string | undefined;
190
+ startedAt?: string | undefined;
191
+ }[];
192
+ admittedSecondsByProject: Record<string, number>;
193
+ admittedSecondsByAgentClass: Record<string, number>;
194
+ activatedAt?: string | undefined;
195
+ closingAt?: string | undefined;
196
+ endedAt?: string | undefined;
197
+ };
198
+ export type WorkdayPolicy = z.infer<typeof workdayPolicySchema>;
199
+ export type AppliedWorkday = z.infer<typeof appliedWorkdaySchema>;
@@ -0,0 +1,96 @@
1
+ import { z } from "zod";
2
+ const identifier = z.string().trim().min(1).max(200).regex(/^[A-Za-z0-9][A-Za-z0-9._:/-]*$/u);
3
+ const positiveWeights = z.record(z.number().positive());
4
+ const workdayPolicySchema = z.object({
5
+ durationSeconds: z.number().int().positive(),
6
+ maximumConcurrency: z.number().int().positive(),
7
+ planningSecondsPerAgent: z.number().int().positive(),
8
+ communicationConcurrency: z.number().int().positive(),
9
+ projectWeights: positiveWeights,
10
+ agentClassWeights: positiveWeights
11
+ }).strict();
12
+ const appliedWorkdaySchema = z.object({
13
+ schemaVersion: z.literal("treeseed.workday/v1"),
14
+ id: identifier,
15
+ teamId: identifier,
16
+ policyId: identifier,
17
+ policyRevision: z.number().int().positive(),
18
+ policySnapshot: workdayPolicySchema,
19
+ state: z.enum(["planned", "active", "closing", "ended"]),
20
+ startsAt: z.string().datetime({ offset: true }),
21
+ endsAt: z.string().datetime({ offset: true }),
22
+ planningRounds: z.array(z.object({
23
+ round: z.union([z.literal(1), z.literal(2)]),
24
+ state: z.enum(["pending", "active", "complete"]),
25
+ assignmentIds: z.array(identifier),
26
+ startedAt: z.string().datetime({ offset: true }).optional(),
27
+ completedAt: z.string().datetime({ offset: true }).optional()
28
+ }).strict()).length(2),
29
+ admittedSecondsByProject: z.record(z.number().int().nonnegative()),
30
+ admittedSecondsByAgentClass: z.record(z.number().int().nonnegative()),
31
+ activatedAt: z.string().datetime({ offset: true }).optional(),
32
+ closingAt: z.string().datetime({ offset: true }).optional(),
33
+ endedAt: z.string().datetime({ offset: true }).optional()
34
+ }).strict();
35
+ function shareDebt(id, weights, actual) {
36
+ const weight = weights[id] ?? 1;
37
+ const totalWeight = Object.values(weights).reduce((sum, value) => sum + value, 0) || 1;
38
+ const totalActual = [...actual.values()].reduce((sum, value) => sum + value, 0);
39
+ return totalActual * weight / totalWeight - (actual.get(id) ?? 0);
40
+ }
41
+ function selectFairReadyNode(nodes, usage, policy) {
42
+ if (!nodes.length) return null;
43
+ const projectActual = /* @__PURE__ */ new Map();
44
+ const classActual = /* @__PURE__ */ new Map();
45
+ for (const entry of usage) {
46
+ projectActual.set(entry.projectId, (projectActual.get(entry.projectId) ?? 0) + entry.seconds);
47
+ classActual.set(`${entry.projectId}:${entry.agentClass}`, (classActual.get(`${entry.projectId}:${entry.agentClass}`) ?? 0) + entry.seconds);
48
+ }
49
+ const projects = [...new Set(nodes.map((node) => node.projectId))].sort((left, right) => shareDebt(right, policy.projectWeights, projectActual) - shareDebt(left, policy.projectWeights, projectActual) || left.localeCompare(right));
50
+ const projectId = projects[0];
51
+ const projectNodes = nodes.filter((node) => node.projectId === projectId);
52
+ const classWeights = Object.fromEntries([...new Set(projectNodes.map((node) => node.agentClass))].map((agentClass) => [agentClass, policy.agentClassWeights[agentClass] ?? 1]));
53
+ const projectClassActual = new Map([...classActual].filter(([key]) => key.startsWith(`${projectId}:`)).map(([key, value]) => [key.slice(projectId.length + 1), value]));
54
+ const classes = [...new Set(projectNodes.map((node) => node.agentClass))].sort((left, right) => shareDebt(right, classWeights, projectClassActual) - shareDebt(left, classWeights, projectClassActual) || left.localeCompare(right));
55
+ return projectNodes.filter((node) => node.agentClass === classes[0]).sort((left, right) => right.graphPriority - left.graphPriority || Date.parse(left.readyAt) - Date.parse(right.readyAt) || left.id.localeCompare(right))[0] ?? null;
56
+ }
57
+ function compilePlanningRounds(workdayId, agentIds, planningSecondsPerAgent) {
58
+ const agents = [...new Set(agentIds)].sort();
59
+ return [1, 2].flatMap((round) => agents.map((agentId) => ({
60
+ id: `planning:${workdayId}:${round}:${agentId}`,
61
+ agentId,
62
+ round,
63
+ maximumSeconds: planningSecondsPerAgent,
64
+ dependsOn: round === 1 ? [] : agents.map((candidate) => `planning:${workdayId}:1:${candidate}`)
65
+ })));
66
+ }
67
+ function compileWorkday(input) {
68
+ const policy = workdayPolicySchema.parse(input.policy);
69
+ const assignments = compilePlanningRounds(input.id, input.agentIds, policy.planningSecondsPerAgent);
70
+ const startsAt = new Date(input.startsAt).toISOString();
71
+ return appliedWorkdaySchema.parse({
72
+ schemaVersion: "treeseed.workday/v1",
73
+ id: input.id,
74
+ teamId: input.teamId,
75
+ policyId: input.policyId,
76
+ policyRevision: input.policyRevision,
77
+ policySnapshot: policy,
78
+ state: "planned",
79
+ startsAt,
80
+ endsAt: new Date(Date.parse(startsAt) + policy.durationSeconds * 1e3).toISOString(),
81
+ planningRounds: [1, 2].map((round) => ({
82
+ round,
83
+ state: "pending",
84
+ assignmentIds: assignments.filter((assignment) => assignment.round === round).map((assignment) => assignment.id)
85
+ })),
86
+ admittedSecondsByProject: {},
87
+ admittedSecondsByAgentClass: {}
88
+ });
89
+ }
90
+ export {
91
+ appliedWorkdaySchema,
92
+ compilePlanningRounds,
93
+ compileWorkday,
94
+ selectFairReadyNode,
95
+ workdayPolicySchema
96
+ };