@themoltnet/agent-daemon 0.32.0 → 0.32.2
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/README.md +23 -2
- package/dist/main.js +1275 -33
- package/package.json +4 -4
package/dist/main.js
CHANGED
|
@@ -12,8 +12,9 @@ import { parseArgs, promisify } from "node:util";
|
|
|
12
12
|
import { AgentRuntime, ApiTaskReporter, ApiTaskSource, PollingApiTaskSource } from "@themoltnet/agent-runtime";
|
|
13
13
|
import { createPiRetryTriage, createPiTaskExecutor, findMainWorktree, normalizeRetryTriageResult, redactRetryTriageSecrets } from "@themoltnet/pi-extension";
|
|
14
14
|
import { execFile, execFileSync } from "node:child_process";
|
|
15
|
-
import { accessSync, constants, createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync } from "node:fs";
|
|
15
|
+
import { accessSync, constants, createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync, realpathSync, rmSync } from "node:fs";
|
|
16
16
|
import { AuthenticationError, MoltNetError, connect } from "@themoltnet/sdk";
|
|
17
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
17
18
|
import { once } from "node:events";
|
|
18
19
|
import { pino, transport } from "pino";
|
|
19
20
|
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
|
|
@@ -25,7 +26,6 @@ import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
25
26
|
import { getModel } from "@earendil-works/pi-ai";
|
|
26
27
|
import { mkdir, realpath, stat } from "node:fs/promises";
|
|
27
28
|
import { pipeline } from "node:stream/promises";
|
|
28
|
-
import { createHash } from "node:crypto";
|
|
29
29
|
import { Writable } from "node:stream";
|
|
30
30
|
import { createGzip } from "node:zlib";
|
|
31
31
|
//#region ../../libs/observability/src/instrumentation.ts
|
|
@@ -4454,6 +4454,875 @@ function deepFreeze(value) {
|
|
|
4454
4454
|
deepFreeze(RUNTIME_PROFILE_CONTEXT_CATALOGUE);
|
|
4455
4455
|
Object.freeze(Object.keys(RUNTIME_PROFILE_CONTEXT_CATALOGUE.recipes));
|
|
4456
4456
|
//#endregion
|
|
4457
|
+
//#region ../../libs/models/src/preview-sign.ts
|
|
4458
|
+
function schemaRef$1(schema, id) {
|
|
4459
|
+
return Unsafe(Ref$1(id));
|
|
4460
|
+
}
|
|
4461
|
+
var PreviewSignBase64UrlSchema = String$1({
|
|
4462
|
+
$id: "PreviewSignBase64Url",
|
|
4463
|
+
minLength: 1,
|
|
4464
|
+
maxLength: 5462,
|
|
4465
|
+
pattern: "^[A-Za-z0-9_-]+$"
|
|
4466
|
+
});
|
|
4467
|
+
var PreviewSignSha256Base64UrlSchema = String$1({
|
|
4468
|
+
$id: "PreviewSignSha256Base64Url",
|
|
4469
|
+
minLength: 43,
|
|
4470
|
+
maxLength: 43,
|
|
4471
|
+
pattern: "^[A-Za-z0-9_-]+$"
|
|
4472
|
+
});
|
|
4473
|
+
var PreviewSignP256DerSignatureBase64UrlSchema = String$1({
|
|
4474
|
+
$id: "PreviewSignP256DerSignatureBase64Url",
|
|
4475
|
+
minLength: 11,
|
|
4476
|
+
maxLength: 96,
|
|
4477
|
+
pattern: "^[A-Za-z0-9_-]+$"
|
|
4478
|
+
});
|
|
4479
|
+
var PreviewSignEs256PublicKeySchema = _Object_({
|
|
4480
|
+
kty: Literal(2),
|
|
4481
|
+
algorithm: Literal(-7),
|
|
4482
|
+
curve: Literal(1),
|
|
4483
|
+
x: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url"),
|
|
4484
|
+
y: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url")
|
|
4485
|
+
}, {
|
|
4486
|
+
$id: "PreviewSignEs256PublicKey",
|
|
4487
|
+
additionalProperties: false
|
|
4488
|
+
});
|
|
4489
|
+
var PreviewSignEcdhEsHkdf256PublicKeySchema = _Object_({
|
|
4490
|
+
kty: Literal(2),
|
|
4491
|
+
algorithm: Literal(-25),
|
|
4492
|
+
curve: Literal(1),
|
|
4493
|
+
x: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url"),
|
|
4494
|
+
y: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url")
|
|
4495
|
+
}, {
|
|
4496
|
+
$id: "PreviewSignEcdhEsHkdf256PublicKey",
|
|
4497
|
+
additionalProperties: false
|
|
4498
|
+
});
|
|
4499
|
+
var PreviewSignEsp256PublicKeySchema = _Object_({
|
|
4500
|
+
kty: Literal(2),
|
|
4501
|
+
algorithm: Literal(-9),
|
|
4502
|
+
curve: Literal(1),
|
|
4503
|
+
x: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url"),
|
|
4504
|
+
y: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url")
|
|
4505
|
+
}, {
|
|
4506
|
+
$id: "PreviewSignEsp256PublicKey",
|
|
4507
|
+
additionalProperties: false
|
|
4508
|
+
});
|
|
4509
|
+
var PreviewSignArkgSeedPublicKeySchema = _Object_({
|
|
4510
|
+
kty: Literal(-65537),
|
|
4511
|
+
algorithm: Literal(-65700),
|
|
4512
|
+
derivedAlgorithm: Literal(-9),
|
|
4513
|
+
blindingKey: schemaRef$1(PreviewSignEs256PublicKeySchema, "PreviewSignEs256PublicKey"),
|
|
4514
|
+
kemKey: schemaRef$1(PreviewSignEcdhEsHkdf256PublicKeySchema, "PreviewSignEcdhEsHkdf256PublicKey")
|
|
4515
|
+
}, {
|
|
4516
|
+
$id: "PreviewSignArkgSeedPublicKey",
|
|
4517
|
+
additionalProperties: false
|
|
4518
|
+
});
|
|
4519
|
+
var PreviewSignPublicMaterialSchema = _Object_({
|
|
4520
|
+
version: Literal(1),
|
|
4521
|
+
outerCredentialId: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url"),
|
|
4522
|
+
outerPublicKey: schemaRef$1(PreviewSignEs256PublicKeySchema, "PreviewSignEs256PublicKey"),
|
|
4523
|
+
previewKeyHandle: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url"),
|
|
4524
|
+
seedPublicKey: schemaRef$1(PreviewSignArkgSeedPublicKeySchema, "PreviewSignArkgSeedPublicKey")
|
|
4525
|
+
}, {
|
|
4526
|
+
$id: "PreviewSignPublicMaterial",
|
|
4527
|
+
additionalProperties: false
|
|
4528
|
+
});
|
|
4529
|
+
var PreviewSignChallengeSchema = _Object_({
|
|
4530
|
+
verificationMethod: Literal("human-hardware-previewsign"),
|
|
4531
|
+
version: Literal(1),
|
|
4532
|
+
envelope: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url"),
|
|
4533
|
+
digest: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url"),
|
|
4534
|
+
additionalArguments: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url"),
|
|
4535
|
+
outerCredentialId: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url"),
|
|
4536
|
+
outerPublicKey: schemaRef$1(PreviewSignEs256PublicKeySchema, "PreviewSignEs256PublicKey"),
|
|
4537
|
+
previewKeyHandle: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url")
|
|
4538
|
+
}, {
|
|
4539
|
+
$id: "PreviewSignChallenge",
|
|
4540
|
+
additionalProperties: false
|
|
4541
|
+
});
|
|
4542
|
+
var PreviewSignChallengeValueSchema = _Object_({
|
|
4543
|
+
verificationMethod: Literal("human-hardware-previewsign"),
|
|
4544
|
+
value: schemaRef$1(PreviewSignChallengeSchema, "PreviewSignChallenge")
|
|
4545
|
+
}, {
|
|
4546
|
+
$id: "PreviewSignChallengeValue",
|
|
4547
|
+
additionalProperties: false
|
|
4548
|
+
});
|
|
4549
|
+
var PreviewSignChallengeOperationSchema = Union([Literal("credential-registration"), Literal("signing-request")], { $id: "PreviewSignChallengeOperation" });
|
|
4550
|
+
var PreviewSignReceiptSchema = _Object_({
|
|
4551
|
+
version: Literal(1),
|
|
4552
|
+
signature: schemaRef$1(PreviewSignP256DerSignatureBase64UrlSchema, "PreviewSignP256DerSignatureBase64Url")
|
|
4553
|
+
}, {
|
|
4554
|
+
$id: "PreviewSignReceipt",
|
|
4555
|
+
additionalProperties: false
|
|
4556
|
+
});
|
|
4557
|
+
var PreviewSignReceiptValueSchema = _Object_({
|
|
4558
|
+
verificationMethod: Literal("human-hardware-previewsign"),
|
|
4559
|
+
value: schemaRef$1(PreviewSignReceiptSchema, "PreviewSignReceipt")
|
|
4560
|
+
}, {
|
|
4561
|
+
$id: "PreviewSignReceiptValue",
|
|
4562
|
+
additionalProperties: false
|
|
4563
|
+
});
|
|
4564
|
+
var previewSignSchemaContext = {
|
|
4565
|
+
PreviewSignBase64Url: PreviewSignBase64UrlSchema,
|
|
4566
|
+
PreviewSignSha256Base64Url: PreviewSignSha256Base64UrlSchema,
|
|
4567
|
+
PreviewSignP256DerSignatureBase64Url: PreviewSignP256DerSignatureBase64UrlSchema,
|
|
4568
|
+
PreviewSignEs256PublicKey: PreviewSignEs256PublicKeySchema,
|
|
4569
|
+
PreviewSignEcdhEsHkdf256PublicKey: PreviewSignEcdhEsHkdf256PublicKeySchema,
|
|
4570
|
+
PreviewSignEsp256PublicKey: PreviewSignEsp256PublicKeySchema,
|
|
4571
|
+
PreviewSignArkgSeedPublicKey: PreviewSignArkgSeedPublicKeySchema,
|
|
4572
|
+
PreviewSignPublicMaterial: PreviewSignPublicMaterialSchema,
|
|
4573
|
+
PreviewSignChallenge: PreviewSignChallengeSchema,
|
|
4574
|
+
PreviewSignChallengeValue: PreviewSignChallengeValueSchema,
|
|
4575
|
+
PreviewSignChallengeOperation: PreviewSignChallengeOperationSchema,
|
|
4576
|
+
PreviewSignReceipt: PreviewSignReceiptSchema,
|
|
4577
|
+
PreviewSignReceiptValue: PreviewSignReceiptValueSchema
|
|
4578
|
+
};
|
|
4579
|
+
//#endregion
|
|
4580
|
+
//#region ../../libs/models/src/verification-method.ts
|
|
4581
|
+
/**
|
|
4582
|
+
* Persisted and wire-level signing verification method identifiers.
|
|
4583
|
+
*
|
|
4584
|
+
* This vocabulary is append-only. Never rename, remove, or change an existing
|
|
4585
|
+
* value: PostgreSQL rows, workflow inputs, and API clients persist these exact
|
|
4586
|
+
* strings. Future signing methods must add a new property and value.
|
|
4587
|
+
*/
|
|
4588
|
+
var VERIFICATION_METHOD = {
|
|
4589
|
+
AgentEd25519: "agent-ed25519",
|
|
4590
|
+
HumanHardwarePreviewSign: "human-hardware-previewsign"
|
|
4591
|
+
};
|
|
4592
|
+
VERIFICATION_METHOD.AgentEd25519, VERIFICATION_METHOD.HumanHardwarePreviewSign;
|
|
4593
|
+
//#endregion
|
|
4594
|
+
//#region ../../libs/models/src/schemas.ts
|
|
4595
|
+
var UuidSchema = String$1({
|
|
4596
|
+
format: "uuid",
|
|
4597
|
+
description: "UUID v4 identifier"
|
|
4598
|
+
});
|
|
4599
|
+
var TimestampSchema = String$1({
|
|
4600
|
+
format: "date-time",
|
|
4601
|
+
description: "ISO 8601 timestamp"
|
|
4602
|
+
});
|
|
4603
|
+
Union([Literal(VERIFICATION_METHOD.AgentEd25519), Literal(VERIFICATION_METHOD.HumanHardwarePreviewSign)], { description: "Stable signing verification method identifier" });
|
|
4604
|
+
Union([
|
|
4605
|
+
Literal("private"),
|
|
4606
|
+
Literal("moltnet"),
|
|
4607
|
+
Literal("public")
|
|
4608
|
+
], { description: "Entry visibility level" });
|
|
4609
|
+
var ENTRY_TYPE_VALUES = [
|
|
4610
|
+
"episodic",
|
|
4611
|
+
"semantic",
|
|
4612
|
+
"procedural",
|
|
4613
|
+
"reflection"
|
|
4614
|
+
];
|
|
4615
|
+
var EntryTypeSchema = Union([
|
|
4616
|
+
Literal("episodic"),
|
|
4617
|
+
Literal("semantic"),
|
|
4618
|
+
Literal("procedural"),
|
|
4619
|
+
Literal("reflection")
|
|
4620
|
+
], { description: "Entry memory type" });
|
|
4621
|
+
/** Regex fragment matching a single entry type value. */
|
|
4622
|
+
var ENTRY_TYPE_PATTERN = `(${ENTRY_TYPE_VALUES.join("|")})`;
|
|
4623
|
+
`${ENTRY_TYPE_PATTERN}${ENTRY_TYPE_PATTERN}`, ENTRY_TYPE_VALUES.length - 1;
|
|
4624
|
+
var PublicKeySchema = String$1({
|
|
4625
|
+
pattern: "^ed25519:[A-Za-z0-9+/=]+$",
|
|
4626
|
+
description: "Ed25519 public key with prefix"
|
|
4627
|
+
});
|
|
4628
|
+
var FingerprintSchema = String$1({
|
|
4629
|
+
pattern: "^[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}$",
|
|
4630
|
+
description: "Key fingerprint (A1B2-C3D4-E5F6-G7H8)"
|
|
4631
|
+
});
|
|
4632
|
+
_Object_({
|
|
4633
|
+
title: Optional(String$1({ maxLength: 255 })),
|
|
4634
|
+
content: String$1({
|
|
4635
|
+
minLength: 1,
|
|
4636
|
+
maxLength: 1e5
|
|
4637
|
+
}),
|
|
4638
|
+
tags: Optional(_Array_(String$1({ maxLength: 128 }), { maxItems: 20 }))
|
|
4639
|
+
});
|
|
4640
|
+
_Object_({
|
|
4641
|
+
title: Optional(String$1({ maxLength: 255 })),
|
|
4642
|
+
content: Optional(String$1({
|
|
4643
|
+
minLength: 1,
|
|
4644
|
+
maxLength: 1e5
|
|
4645
|
+
})),
|
|
4646
|
+
tags: Optional(_Array_(String$1({ maxLength: 128 }), { maxItems: 20 }))
|
|
4647
|
+
});
|
|
4648
|
+
_Object_({
|
|
4649
|
+
query: Optional(String$1({
|
|
4650
|
+
minLength: 1,
|
|
4651
|
+
maxLength: 500
|
|
4652
|
+
})),
|
|
4653
|
+
tags: Optional(_Array_(String$1({ maxLength: 128 }), {
|
|
4654
|
+
minItems: 1,
|
|
4655
|
+
maxItems: 20,
|
|
4656
|
+
description: "Filter: entry must have ALL specified tags"
|
|
4657
|
+
})),
|
|
4658
|
+
limit: Optional(Number$1({
|
|
4659
|
+
minimum: 1,
|
|
4660
|
+
maximum: 100,
|
|
4661
|
+
default: 20
|
|
4662
|
+
})),
|
|
4663
|
+
offset: Optional(Number$1({
|
|
4664
|
+
minimum: 0,
|
|
4665
|
+
default: 0
|
|
4666
|
+
}))
|
|
4667
|
+
});
|
|
4668
|
+
_Object_({
|
|
4669
|
+
identityId: UuidSchema,
|
|
4670
|
+
publicKey: PublicKeySchema,
|
|
4671
|
+
fingerprint: FingerprintSchema,
|
|
4672
|
+
createdAt: TimestampSchema
|
|
4673
|
+
});
|
|
4674
|
+
_Object_({
|
|
4675
|
+
publicKey: PublicKeySchema,
|
|
4676
|
+
fingerprint: FingerprintSchema
|
|
4677
|
+
});
|
|
4678
|
+
_Object_({ message: String$1({
|
|
4679
|
+
minLength: 1,
|
|
4680
|
+
maxLength: 1e4
|
|
4681
|
+
}) });
|
|
4682
|
+
_Object_({
|
|
4683
|
+
message: String$1(),
|
|
4684
|
+
signature: String$1({ description: "Base64 encoded Ed25519 signature" }),
|
|
4685
|
+
publicKey: PublicKeySchema
|
|
4686
|
+
});
|
|
4687
|
+
_Object_({
|
|
4688
|
+
message: String$1({
|
|
4689
|
+
minLength: 1,
|
|
4690
|
+
maxLength: 1e4
|
|
4691
|
+
}),
|
|
4692
|
+
signature: String$1({ description: "Base64 encoded signature" }),
|
|
4693
|
+
publicKey: PublicKeySchema
|
|
4694
|
+
});
|
|
4695
|
+
_Object_({
|
|
4696
|
+
valid: Boolean$1(),
|
|
4697
|
+
signer: Optional(_Object_({ fingerprint: FingerprintSchema }))
|
|
4698
|
+
});
|
|
4699
|
+
var BaseAuthContextSchema = _Object_({
|
|
4700
|
+
identityId: UuidSchema,
|
|
4701
|
+
scopes: _Array_(String$1()),
|
|
4702
|
+
subjectType: Union([Literal("agent"), Literal("human")]),
|
|
4703
|
+
currentTeamId: Union([UuidSchema, Null()])
|
|
4704
|
+
});
|
|
4705
|
+
Union([Intersect([BaseAuthContextSchema, _Object_({
|
|
4706
|
+
subjectType: Literal("agent"),
|
|
4707
|
+
publicKey: PublicKeySchema,
|
|
4708
|
+
fingerprint: FingerprintSchema,
|
|
4709
|
+
clientId: String$1()
|
|
4710
|
+
})]), Intersect([BaseAuthContextSchema, _Object_({
|
|
4711
|
+
subjectType: Literal("human"),
|
|
4712
|
+
clientId: Union([String$1(), Null()])
|
|
4713
|
+
})])]);
|
|
4714
|
+
_Object_({
|
|
4715
|
+
success: Boolean$1(),
|
|
4716
|
+
message: Optional(String$1())
|
|
4717
|
+
});
|
|
4718
|
+
_Object_({ diaryId: UuidSchema });
|
|
4719
|
+
_Object_({
|
|
4720
|
+
diaryId: UuidSchema,
|
|
4721
|
+
entryId: UuidSchema
|
|
4722
|
+
});
|
|
4723
|
+
_Object_({ entryId: UuidSchema });
|
|
4724
|
+
_Object_({ id: UuidSchema });
|
|
4725
|
+
_Object_({
|
|
4726
|
+
publicKey: PublicKeySchema,
|
|
4727
|
+
fingerprint: FingerprintSchema,
|
|
4728
|
+
agentName: String$1({
|
|
4729
|
+
minLength: 1,
|
|
4730
|
+
maxLength: 34
|
|
4731
|
+
}),
|
|
4732
|
+
org: Optional(String$1({
|
|
4733
|
+
minLength: 1,
|
|
4734
|
+
maxLength: 39,
|
|
4735
|
+
pattern: "^[a-zA-Z0-9-]+$",
|
|
4736
|
+
description: "GitHub organization name. When provided, the GitHub App will be created under this org instead of the personal account."
|
|
4737
|
+
}))
|
|
4738
|
+
});
|
|
4739
|
+
_Object_({
|
|
4740
|
+
workflowId: String$1(),
|
|
4741
|
+
manifestFormUrl: String$1()
|
|
4742
|
+
});
|
|
4743
|
+
_Object_({
|
|
4744
|
+
status: Union([
|
|
4745
|
+
Literal("awaiting_github"),
|
|
4746
|
+
Literal("github_code_ready"),
|
|
4747
|
+
Literal("awaiting_installation"),
|
|
4748
|
+
Literal("completed"),
|
|
4749
|
+
Literal("failed")
|
|
4750
|
+
]),
|
|
4751
|
+
githubCode: Optional(String$1()),
|
|
4752
|
+
identityId: Optional(String$1()),
|
|
4753
|
+
clientId: Optional(String$1()),
|
|
4754
|
+
clientSecret: Optional(String$1()),
|
|
4755
|
+
installationId: Optional(String$1())
|
|
4756
|
+
});
|
|
4757
|
+
_Object_({
|
|
4758
|
+
wf: String$1({
|
|
4759
|
+
minLength: 1,
|
|
4760
|
+
description: "Workflow ID baked into setup_url"
|
|
4761
|
+
}),
|
|
4762
|
+
installation_id: String$1({ minLength: 1 }),
|
|
4763
|
+
setup_action: Optional(String$1())
|
|
4764
|
+
});
|
|
4765
|
+
_Object_({ id: UuidSchema });
|
|
4766
|
+
_Object_({
|
|
4767
|
+
id: UuidSchema,
|
|
4768
|
+
subjectId: UuidSchema
|
|
4769
|
+
});
|
|
4770
|
+
_Object_({
|
|
4771
|
+
id: UuidSchema,
|
|
4772
|
+
inviteId: UuidSchema
|
|
4773
|
+
});
|
|
4774
|
+
_Object_({ name: String$1({
|
|
4775
|
+
minLength: 1,
|
|
4776
|
+
maxLength: 255
|
|
4777
|
+
}) });
|
|
4778
|
+
_Object_({
|
|
4779
|
+
role: Optional(Union([Literal("manager"), Literal("member")])),
|
|
4780
|
+
maxUses: Optional(Integer({
|
|
4781
|
+
minimum: 1,
|
|
4782
|
+
default: 1
|
|
4783
|
+
})),
|
|
4784
|
+
expiresInHours: Optional(Integer({
|
|
4785
|
+
minimum: 1,
|
|
4786
|
+
maximum: 720,
|
|
4787
|
+
default: 168
|
|
4788
|
+
}))
|
|
4789
|
+
});
|
|
4790
|
+
_Object_({ code: String$1({ minLength: 1 }) });
|
|
4791
|
+
_Object_({ role: Union([Literal("manager"), Literal("member")]) });
|
|
4792
|
+
var TeamRoleSchema = Union([
|
|
4793
|
+
Literal("owner"),
|
|
4794
|
+
Literal("manager"),
|
|
4795
|
+
Literal("member")
|
|
4796
|
+
]);
|
|
4797
|
+
_Object_({
|
|
4798
|
+
id: UuidSchema,
|
|
4799
|
+
name: String$1()
|
|
4800
|
+
});
|
|
4801
|
+
var DateTimeUnsafe = Unsafe(String$1({ format: "date-time" }));
|
|
4802
|
+
_Object_({
|
|
4803
|
+
id: UuidSchema,
|
|
4804
|
+
code: String$1(),
|
|
4805
|
+
role: Union([Literal("manager"), Literal("member")]),
|
|
4806
|
+
maxUses: Integer(),
|
|
4807
|
+
useCount: Integer(),
|
|
4808
|
+
expiresAt: DateTimeUnsafe,
|
|
4809
|
+
createdAt: DateTimeUnsafe
|
|
4810
|
+
});
|
|
4811
|
+
var TeamMemberSchema = _Object_({
|
|
4812
|
+
subjectId: UuidSchema,
|
|
4813
|
+
subjectType: Union([Literal("agent"), Literal("human")]),
|
|
4814
|
+
role: TeamRoleSchema,
|
|
4815
|
+
displayName: String$1(),
|
|
4816
|
+
fingerprint: Optional(String$1()),
|
|
4817
|
+
email: Optional(String$1())
|
|
4818
|
+
});
|
|
4819
|
+
_Object_({
|
|
4820
|
+
id: UuidSchema,
|
|
4821
|
+
name: String$1(),
|
|
4822
|
+
personal: Boolean$1(),
|
|
4823
|
+
status: String$1(),
|
|
4824
|
+
role: TeamRoleSchema
|
|
4825
|
+
});
|
|
4826
|
+
_Object_({
|
|
4827
|
+
id: UuidSchema,
|
|
4828
|
+
name: String$1(),
|
|
4829
|
+
status: String$1(),
|
|
4830
|
+
personal: Boolean$1(),
|
|
4831
|
+
createdAt: DateTimeUnsafe,
|
|
4832
|
+
updatedAt: DateTimeUnsafe,
|
|
4833
|
+
members: _Array_(TeamMemberSchema)
|
|
4834
|
+
});
|
|
4835
|
+
_Object_({
|
|
4836
|
+
teamId: UuidSchema,
|
|
4837
|
+
role: Union([Literal("manager"), Literal("member")])
|
|
4838
|
+
});
|
|
4839
|
+
_Object_({
|
|
4840
|
+
updated: Boolean$1(),
|
|
4841
|
+
role: Union([Literal("manager"), Literal("member")])
|
|
4842
|
+
});
|
|
4843
|
+
_Object_({ deleted: Boolean$1() });
|
|
4844
|
+
_Object_({ removed: Boolean$1() });
|
|
4845
|
+
var FoundingMemberSchema = _Object_({
|
|
4846
|
+
subjectId: UuidSchema,
|
|
4847
|
+
subjectNs: Union([Literal("Agent"), Literal("Human")]),
|
|
4848
|
+
role: Union([
|
|
4849
|
+
Literal("owner"),
|
|
4850
|
+
Literal("manager"),
|
|
4851
|
+
Literal("member")
|
|
4852
|
+
])
|
|
4853
|
+
});
|
|
4854
|
+
_Object_({
|
|
4855
|
+
name: String$1({
|
|
4856
|
+
minLength: 1,
|
|
4857
|
+
maxLength: 255
|
|
4858
|
+
}),
|
|
4859
|
+
foundingMembers: Optional(_Array_(FoundingMemberSchema, { minItems: 1 }))
|
|
4860
|
+
});
|
|
4861
|
+
_Object_({
|
|
4862
|
+
id: UuidSchema,
|
|
4863
|
+
name: String$1(),
|
|
4864
|
+
status: String$1(),
|
|
4865
|
+
workflowId: Optional(String$1())
|
|
4866
|
+
});
|
|
4867
|
+
_Object_({});
|
|
4868
|
+
_Object_({
|
|
4869
|
+
accepted: Boolean$1(),
|
|
4870
|
+
teamStatus: String$1()
|
|
4871
|
+
});
|
|
4872
|
+
_Object_({ destinationTeamId: UuidSchema });
|
|
4873
|
+
_Object_({ transferId: UuidSchema });
|
|
4874
|
+
_Object_({ items: _Array_(_Object_({
|
|
4875
|
+
id: UuidSchema,
|
|
4876
|
+
diaryId: UuidSchema,
|
|
4877
|
+
sourceTeamId: UuidSchema,
|
|
4878
|
+
destinationTeamId: UuidSchema,
|
|
4879
|
+
status: String$1(),
|
|
4880
|
+
initiatedBy: UuidSchema,
|
|
4881
|
+
expiresAt: Unsafe(String$1({ format: "date-time" })),
|
|
4882
|
+
createdAt: Unsafe(String$1({ format: "date-time" }))
|
|
4883
|
+
})) });
|
|
4884
|
+
_Object_({ groupId: UuidSchema });
|
|
4885
|
+
_Object_({
|
|
4886
|
+
groupId: UuidSchema,
|
|
4887
|
+
subjectId: UuidSchema
|
|
4888
|
+
});
|
|
4889
|
+
_Object_({ name: String$1({
|
|
4890
|
+
minLength: 1,
|
|
4891
|
+
maxLength: 255
|
|
4892
|
+
}) });
|
|
4893
|
+
_Object_({
|
|
4894
|
+
subjectId: UuidSchema,
|
|
4895
|
+
subjectNs: Optional(Union([Literal("Agent"), Literal("Human")]))
|
|
4896
|
+
});
|
|
4897
|
+
_Object_({
|
|
4898
|
+
id: UuidSchema,
|
|
4899
|
+
name: String$1(),
|
|
4900
|
+
teamId: UuidSchema
|
|
4901
|
+
});
|
|
4902
|
+
var GroupMemberResponseSchema = _Object_({
|
|
4903
|
+
subjectId: UuidSchema,
|
|
4904
|
+
subjectNs: String$1()
|
|
4905
|
+
});
|
|
4906
|
+
_Object_({
|
|
4907
|
+
id: UuidSchema,
|
|
4908
|
+
name: String$1(),
|
|
4909
|
+
teamId: UuidSchema,
|
|
4910
|
+
createdAt: DateTimeUnsafe,
|
|
4911
|
+
members: _Array_(GroupMemberResponseSchema)
|
|
4912
|
+
});
|
|
4913
|
+
var DiaryGrantRoleSchema = Union([Literal("writer"), Literal("manager")]);
|
|
4914
|
+
var GrantSubjectNsSchema = Union([
|
|
4915
|
+
Literal("Agent"),
|
|
4916
|
+
Literal("Human"),
|
|
4917
|
+
Literal("Group")
|
|
4918
|
+
]);
|
|
4919
|
+
_Object_({
|
|
4920
|
+
subjectId: UuidSchema,
|
|
4921
|
+
subjectNs: GrantSubjectNsSchema,
|
|
4922
|
+
role: DiaryGrantRoleSchema
|
|
4923
|
+
});
|
|
4924
|
+
_Object_({
|
|
4925
|
+
subjectId: UuidSchema,
|
|
4926
|
+
subjectNs: GrantSubjectNsSchema,
|
|
4927
|
+
role: DiaryGrantRoleSchema
|
|
4928
|
+
});
|
|
4929
|
+
_Object_({ grants: _Array_(_Object_({
|
|
4930
|
+
subjectId: UuidSchema,
|
|
4931
|
+
subjectNs: GrantSubjectNsSchema,
|
|
4932
|
+
role: DiaryGrantRoleSchema
|
|
4933
|
+
})) });
|
|
4934
|
+
_Object_({ revoked: Boolean$1() });
|
|
4935
|
+
_Object_({ "x-moltnet-team-id": String$1({
|
|
4936
|
+
format: "uuid",
|
|
4937
|
+
description: "Team ID (UUID) that will own the resource. Required."
|
|
4938
|
+
}) });
|
|
4939
|
+
_Object_({ "x-moltnet-team-id": Optional(String$1({
|
|
4940
|
+
format: "uuid",
|
|
4941
|
+
description: "Team ID (UUID) for scoping the request. Optional."
|
|
4942
|
+
})) });
|
|
4943
|
+
_Object_({
|
|
4944
|
+
kind: Literal("agent"),
|
|
4945
|
+
identityId: UuidSchema,
|
|
4946
|
+
fingerprint: FingerprintSchema,
|
|
4947
|
+
publicKey: PublicKeySchema
|
|
4948
|
+
}, {
|
|
4949
|
+
$id: "AgentPrincipal",
|
|
4950
|
+
additionalProperties: false
|
|
4951
|
+
});
|
|
4952
|
+
_Object_({
|
|
4953
|
+
kind: Literal("human"),
|
|
4954
|
+
humanId: UuidSchema,
|
|
4955
|
+
identityId: Union([UuidSchema, Null()])
|
|
4956
|
+
}, {
|
|
4957
|
+
$id: "HumanPrincipal",
|
|
4958
|
+
additionalProperties: false
|
|
4959
|
+
});
|
|
4960
|
+
var principalUnionVariants = [_Object_({
|
|
4961
|
+
kind: Literal("agent"),
|
|
4962
|
+
identityId: UuidSchema,
|
|
4963
|
+
fingerprint: FingerprintSchema,
|
|
4964
|
+
publicKey: PublicKeySchema
|
|
4965
|
+
}, { additionalProperties: false }), _Object_({
|
|
4966
|
+
kind: Literal("human"),
|
|
4967
|
+
humanId: UuidSchema,
|
|
4968
|
+
identityId: Union([UuidSchema, Null()])
|
|
4969
|
+
}, { additionalProperties: false })];
|
|
4970
|
+
Union(principalUnionVariants, {
|
|
4971
|
+
$id: "PrincipalIdentity",
|
|
4972
|
+
discriminator: { propertyName: "kind" }
|
|
4973
|
+
});
|
|
4974
|
+
/**
|
|
4975
|
+
* `$id`-less twin of `PrincipalIdentitySchema`. Required anywhere the
|
|
4976
|
+
* schema is **embedded** inline into another schema (MCP `outputSchema`
|
|
4977
|
+
* — every tool that returns a creator-bearing object embeds its own
|
|
4978
|
+
* copy; provenance-graph node `meta.creator`, etc.). Ajv 8 throws
|
|
4979
|
+
* `reference "PrincipalIdentity" resolves to more than one schema` if
|
|
4980
|
+
* the same `$id` appears twice in the same compilation pass, which is
|
|
4981
|
+
* exactly what happens when the MCP server lists tools and Ajv
|
|
4982
|
+
* traverses every advertised `outputSchema`.
|
|
4983
|
+
*
|
|
4984
|
+
* Structurally identical to `PrincipalIdentitySchema` (they share the
|
|
4985
|
+
* variants array); change one, change both.
|
|
4986
|
+
*/
|
|
4987
|
+
var PrincipalIdentitySchemaInline = Union(principalUnionVariants, { discriminator: { propertyName: "kind" } });
|
|
4988
|
+
//#endregion
|
|
4989
|
+
//#region ../../libs/models/src/problem-details.ts
|
|
4990
|
+
var ProblemCodeSchema = Union([
|
|
4991
|
+
Literal("UNAUTHORIZED"),
|
|
4992
|
+
Literal("FORBIDDEN"),
|
|
4993
|
+
Literal("NOT_FOUND"),
|
|
4994
|
+
Literal("CONFLICT"),
|
|
4995
|
+
Literal("UNSUPPORTED_MEDIA_TYPE"),
|
|
4996
|
+
Literal("VALIDATION_FAILED"),
|
|
4997
|
+
Literal("INVALID_CHALLENGE"),
|
|
4998
|
+
Literal("INVALID_SIGNATURE"),
|
|
4999
|
+
Literal("VOUCHER_LIMIT"),
|
|
5000
|
+
Literal("RATE_LIMIT_EXCEEDED"),
|
|
5001
|
+
Literal("SERIALIZATION_EXHAUSTED"),
|
|
5002
|
+
Literal("SIGNING_REQUEST_EXPIRED"),
|
|
5003
|
+
Literal("SIGNING_REQUEST_ALREADY_COMPLETED"),
|
|
5004
|
+
Literal("SIGNING_REQUEST_LIMIT_REACHED"),
|
|
5005
|
+
Literal("REGISTRATION_FAILED"),
|
|
5006
|
+
Literal("UPSTREAM_ERROR"),
|
|
5007
|
+
Literal("SERVICE_UNAVAILABLE"),
|
|
5008
|
+
Literal("INTERNAL_SERVER_ERROR"),
|
|
5009
|
+
Literal("TEAM_PERSONAL_IMMUTABLE"),
|
|
5010
|
+
Literal("TEAM_NOT_ACTIVE"),
|
|
5011
|
+
Literal("INVITE_EXPIRED"),
|
|
5012
|
+
Literal("INVITE_EXHAUSTED"),
|
|
5013
|
+
Literal("TEAM_LAST_OWNER"),
|
|
5014
|
+
Literal("TEAM_ALREADY_ACTIVE"),
|
|
5015
|
+
Literal("TEAM_NOT_FOUNDING"),
|
|
5016
|
+
Literal("FOUNDING_ALREADY_ACCEPTED"),
|
|
5017
|
+
Literal("DIARY_TRANSFER_PENDING"),
|
|
5018
|
+
Literal("DIARY_TRANSFER_NOT_FOUND"),
|
|
5019
|
+
Literal("DIARY_TRANSFER_ALREADY_RESOLVED")
|
|
5020
|
+
]);
|
|
5021
|
+
var ProblemDetailsSchema = _Object_({
|
|
5022
|
+
type: String$1({ format: "uri" }),
|
|
5023
|
+
title: String$1(),
|
|
5024
|
+
status: Integer({
|
|
5025
|
+
minimum: 100,
|
|
5026
|
+
maximum: 599
|
|
5027
|
+
}),
|
|
5028
|
+
code: ProblemCodeSchema,
|
|
5029
|
+
detail: Optional(String$1()),
|
|
5030
|
+
instance: Optional(String$1())
|
|
5031
|
+
}, {
|
|
5032
|
+
$id: "ProblemDetails",
|
|
5033
|
+
additionalProperties: true
|
|
5034
|
+
});
|
|
5035
|
+
_Object_({
|
|
5036
|
+
field: String$1(),
|
|
5037
|
+
message: String$1(),
|
|
5038
|
+
code: Optional(String$1())
|
|
5039
|
+
}, {
|
|
5040
|
+
$id: "ValidationError",
|
|
5041
|
+
additionalProperties: false
|
|
5042
|
+
});
|
|
5043
|
+
_Object_({
|
|
5044
|
+
resource: String$1(),
|
|
5045
|
+
id: Optional(String$1({ format: "uuid" })),
|
|
5046
|
+
keys: Optional(Record(String$1(), String$1()))
|
|
5047
|
+
}, {
|
|
5048
|
+
$id: "ConflictTarget",
|
|
5049
|
+
additionalProperties: false
|
|
5050
|
+
});
|
|
5051
|
+
_Object_({
|
|
5052
|
+
constraint: Optional(String$1()),
|
|
5053
|
+
target: Optional(Ref$1("ConflictTarget"))
|
|
5054
|
+
}, {
|
|
5055
|
+
$id: "ConflictError",
|
|
5056
|
+
additionalProperties: false
|
|
5057
|
+
});
|
|
5058
|
+
var ConflictProblemDetailsSchema = Intersect([ProblemDetailsSchema, _Object_({ conflict: Ref$1("ConflictError") })], { $id: "ConflictProblemDetails" });
|
|
5059
|
+
_Object_({
|
|
5060
|
+
type: String$1(),
|
|
5061
|
+
severity: Number$1(),
|
|
5062
|
+
match: String$1()
|
|
5063
|
+
}, {
|
|
5064
|
+
$id: "InjectionThreat",
|
|
5065
|
+
additionalProperties: false
|
|
5066
|
+
});
|
|
5067
|
+
Intersect([ConflictProblemDetailsSchema, _Object_({ flagged: Optional(_Array_(_Object_({
|
|
5068
|
+
id: String$1({ format: "uuid" }),
|
|
5069
|
+
threats: _Array_(Ref$1("InjectionThreat"))
|
|
5070
|
+
}, { additionalProperties: false }))) })], { $id: "InjectionConflictProblemDetails" });
|
|
5071
|
+
Intersect([ProblemDetailsSchema, _Object_({ errors: _Array_(Ref$1("ValidationError")) })], { $id: "ValidationProblemDetails" });
|
|
5072
|
+
Union([
|
|
5073
|
+
Literal("pack"),
|
|
5074
|
+
Literal("entry"),
|
|
5075
|
+
Literal("rendered_pack")
|
|
5076
|
+
]);
|
|
5077
|
+
var ProvenanceGraphEdgeKindSchema = Union([
|
|
5078
|
+
Literal("includes"),
|
|
5079
|
+
Literal("supersedes"),
|
|
5080
|
+
Literal("rendered_from")
|
|
5081
|
+
]);
|
|
5082
|
+
var ProvenanceGraphPackMetaSchema = _Object_({
|
|
5083
|
+
packId: UuidSchema,
|
|
5084
|
+
diaryId: UuidSchema,
|
|
5085
|
+
packCid: String$1(),
|
|
5086
|
+
packType: String$1(),
|
|
5087
|
+
packCodec: String$1(),
|
|
5088
|
+
pinned: Boolean$1(),
|
|
5089
|
+
createdAt: TimestampSchema,
|
|
5090
|
+
expiresAt: Union([TimestampSchema, Null()]),
|
|
5091
|
+
supersedesPackId: Union([UuidSchema, Null()])
|
|
5092
|
+
});
|
|
5093
|
+
/**
|
|
5094
|
+
* Discriminated creator embedded inside provenance-node response
|
|
5095
|
+
* payloads. Re-uses the shared `PrincipalIdentitySchemaInline` (the
|
|
5096
|
+
* `$id`-less twin) — embedding the named `PrincipalIdentitySchema`
|
|
5097
|
+
* here would clash with the top-level registration via @fastify/swagger
|
|
5098
|
+
* (`reference "PrincipalIdentity" resolves to more than one schema`).
|
|
5099
|
+
*/
|
|
5100
|
+
var ProvenanceGraphCreatorSchema = PrincipalIdentitySchemaInline;
|
|
5101
|
+
var ProvenanceGraphEntryMetaSchema = _Object_({
|
|
5102
|
+
entryId: UuidSchema,
|
|
5103
|
+
diaryId: UuidSchema,
|
|
5104
|
+
entryType: EntryTypeSchema,
|
|
5105
|
+
contentHash: Union([String$1(), Null()]),
|
|
5106
|
+
createdAt: TimestampSchema,
|
|
5107
|
+
updatedAt: TimestampSchema,
|
|
5108
|
+
signed: Boolean$1(),
|
|
5109
|
+
title: Union([String$1(), Null()]),
|
|
5110
|
+
tags: _Array_(String$1()),
|
|
5111
|
+
creator: Optional(ProvenanceGraphCreatorSchema)
|
|
5112
|
+
});
|
|
5113
|
+
var ProvenanceGraphPackNodeSchema = _Object_({
|
|
5114
|
+
id: String$1(),
|
|
5115
|
+
kind: Literal("pack"),
|
|
5116
|
+
label: String$1(),
|
|
5117
|
+
cid: Union([String$1(), Null()]),
|
|
5118
|
+
meta: Intersect([ProvenanceGraphPackMetaSchema, _Object_({ creator: Optional(ProvenanceGraphCreatorSchema) })])
|
|
5119
|
+
});
|
|
5120
|
+
var ProvenanceGraphEntryNodeSchema = _Object_({
|
|
5121
|
+
id: String$1(),
|
|
5122
|
+
kind: Literal("entry"),
|
|
5123
|
+
label: String$1(),
|
|
5124
|
+
cid: Union([String$1(), Null()]),
|
|
5125
|
+
meta: ProvenanceGraphEntryMetaSchema
|
|
5126
|
+
});
|
|
5127
|
+
var ProvenanceGraphRenderedPackMetaSchema = _Object_({
|
|
5128
|
+
renderedPackId: UuidSchema,
|
|
5129
|
+
sourcePackId: UuidSchema,
|
|
5130
|
+
diaryId: UuidSchema,
|
|
5131
|
+
packCid: String$1(),
|
|
5132
|
+
renderMethod: String$1(),
|
|
5133
|
+
totalTokens: Number$1(),
|
|
5134
|
+
pinned: Boolean$1(),
|
|
5135
|
+
createdAt: TimestampSchema,
|
|
5136
|
+
expiresAt: Union([TimestampSchema, Null()]),
|
|
5137
|
+
creator: Optional(ProvenanceGraphCreatorSchema)
|
|
5138
|
+
});
|
|
5139
|
+
var ProvenanceGraphNodeSchema = Union([
|
|
5140
|
+
ProvenanceGraphPackNodeSchema,
|
|
5141
|
+
ProvenanceGraphEntryNodeSchema,
|
|
5142
|
+
_Object_({
|
|
5143
|
+
id: String$1(),
|
|
5144
|
+
kind: Literal("rendered_pack"),
|
|
5145
|
+
label: String$1(),
|
|
5146
|
+
cid: Union([String$1(), Null()]),
|
|
5147
|
+
meta: ProvenanceGraphRenderedPackMetaSchema
|
|
5148
|
+
})
|
|
5149
|
+
]);
|
|
5150
|
+
var ProvenanceGraphEdgeSchema = _Object_({
|
|
5151
|
+
id: String$1(),
|
|
5152
|
+
from: String$1(),
|
|
5153
|
+
to: String$1(),
|
|
5154
|
+
kind: ProvenanceGraphEdgeKindSchema,
|
|
5155
|
+
label: Optional(String$1()),
|
|
5156
|
+
meta: Optional(Record(String$1(), Union([
|
|
5157
|
+
String$1(),
|
|
5158
|
+
Number$1(),
|
|
5159
|
+
Boolean$1(),
|
|
5160
|
+
Null()
|
|
5161
|
+
])))
|
|
5162
|
+
});
|
|
5163
|
+
_Object_({
|
|
5164
|
+
metadata: _Object_({
|
|
5165
|
+
format: Literal("moltnet.provenance-graph/v1"),
|
|
5166
|
+
generatedAt: TimestampSchema,
|
|
5167
|
+
rootNodeId: String$1(),
|
|
5168
|
+
rootPackId: UuidSchema,
|
|
5169
|
+
depth: Number$1({ minimum: 0 })
|
|
5170
|
+
}),
|
|
5171
|
+
nodes: _Array_(ProvenanceGraphNodeSchema),
|
|
5172
|
+
edges: _Array_(ProvenanceGraphEdgeSchema)
|
|
5173
|
+
}, { $id: "ProvenanceGraph" });
|
|
5174
|
+
//#endregion
|
|
5175
|
+
//#region ../../libs/models/src/signer-constraint.ts
|
|
5176
|
+
var SIGNER_CONSTRAINT_TYPE = {
|
|
5177
|
+
Human: "human",
|
|
5178
|
+
TeamRole: "team-role",
|
|
5179
|
+
Group: "group"
|
|
5180
|
+
};
|
|
5181
|
+
Union([
|
|
5182
|
+
_Object_({
|
|
5183
|
+
type: Literal(SIGNER_CONSTRAINT_TYPE.Human),
|
|
5184
|
+
id: String$1({ format: "uuid" })
|
|
5185
|
+
}),
|
|
5186
|
+
_Object_({
|
|
5187
|
+
type: Literal(SIGNER_CONSTRAINT_TYPE.TeamRole),
|
|
5188
|
+
id: TeamRoleSchema
|
|
5189
|
+
}),
|
|
5190
|
+
_Object_({
|
|
5191
|
+
type: Literal(SIGNER_CONSTRAINT_TYPE.Group),
|
|
5192
|
+
id: String$1({ format: "uuid" })
|
|
5193
|
+
})
|
|
5194
|
+
]);
|
|
5195
|
+
//#endregion
|
|
5196
|
+
//#region ../../libs/models/src/signer-protocol.ts
|
|
5197
|
+
function schemaRef(schema) {
|
|
5198
|
+
return Ref$1(schemaId(schema));
|
|
5199
|
+
}
|
|
5200
|
+
function schemaId(schema) {
|
|
5201
|
+
const id = schema.$id;
|
|
5202
|
+
if (typeof id !== "string" || id.length === 0) throw new Error("Signer protocol schemas must have an identifier");
|
|
5203
|
+
return id;
|
|
5204
|
+
}
|
|
5205
|
+
var SignerBase64UrlSchema = PreviewSignBase64UrlSchema;
|
|
5206
|
+
var SignerUuidSchema = String$1({
|
|
5207
|
+
$id: "SignerUuid",
|
|
5208
|
+
pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
|
5209
|
+
});
|
|
5210
|
+
var SignerOperationSchema = Union([
|
|
5211
|
+
Literal("credential-enrollment"),
|
|
5212
|
+
Literal("credential-registration"),
|
|
5213
|
+
Literal("signing-request")
|
|
5214
|
+
], { $id: "SignerOperation" });
|
|
5215
|
+
var SignerChallengeOperationSchema = PreviewSignChallengeOperationSchema;
|
|
5216
|
+
var SignerPreviewSignPublicMaterialSchema = PreviewSignPublicMaterialSchema;
|
|
5217
|
+
var SignerPreviewSignChallengeValueSchema = PreviewSignChallengeValueSchema;
|
|
5218
|
+
var SignerProblemSchema = _Object_({
|
|
5219
|
+
code: String$1({ minLength: 1 }),
|
|
5220
|
+
message: String$1({ minLength: 1 })
|
|
5221
|
+
}, {
|
|
5222
|
+
$id: "SignerProblem",
|
|
5223
|
+
additionalProperties: false
|
|
5224
|
+
});
|
|
5225
|
+
var SignerCeremonyParamsSchema = _Object_({ ceremonyId: Unsafe(schemaRef(SignerBase64UrlSchema)) }, {
|
|
5226
|
+
$id: "SignerCeremonyParams",
|
|
5227
|
+
additionalProperties: false
|
|
5228
|
+
});
|
|
5229
|
+
var SignerSessionSchema = _Object_({
|
|
5230
|
+
version: Literal(1),
|
|
5231
|
+
token: Unsafe(schemaRef(SignerBase64UrlSchema)),
|
|
5232
|
+
expiresAt: String$1()
|
|
5233
|
+
}, {
|
|
5234
|
+
$id: "SignerSession",
|
|
5235
|
+
additionalProperties: false
|
|
5236
|
+
});
|
|
5237
|
+
var SignerEnrollmentCeremonyRequestSchema = _Object_({
|
|
5238
|
+
version: Literal(1),
|
|
5239
|
+
operation: Literal("credential-enrollment"),
|
|
5240
|
+
label: String$1({
|
|
5241
|
+
minLength: 1,
|
|
5242
|
+
maxLength: 255
|
|
5243
|
+
}),
|
|
5244
|
+
teamId: Unsafe(schemaRef(SignerUuidSchema))
|
|
5245
|
+
}, {
|
|
5246
|
+
$id: "SignerEnrollmentCeremonyRequest",
|
|
5247
|
+
additionalProperties: false
|
|
5248
|
+
});
|
|
5249
|
+
var SignerChallengeCeremonyRequestSchema = _Object_({
|
|
5250
|
+
version: Literal(1),
|
|
5251
|
+
operation: Unsafe(schemaRef(SignerChallengeOperationSchema)),
|
|
5252
|
+
resourceId: Unsafe(schemaRef(SignerUuidSchema)),
|
|
5253
|
+
challenge: Unsafe(schemaRef(SignerPreviewSignChallengeValueSchema))
|
|
5254
|
+
}, {
|
|
5255
|
+
$id: "SignerChallengeCeremonyRequest",
|
|
5256
|
+
additionalProperties: false
|
|
5257
|
+
});
|
|
5258
|
+
var SignerCeremonyRequestSchema = Union([Unsafe(schemaRef(SignerEnrollmentCeremonyRequestSchema)), Unsafe(schemaRef(SignerChallengeCeremonyRequestSchema))], { $id: "SignerCeremonyRequest" });
|
|
5259
|
+
var SignerCeremonySchema = _Object_({
|
|
5260
|
+
version: Literal(1),
|
|
5261
|
+
id: Unsafe(schemaRef(SignerBase64UrlSchema)),
|
|
5262
|
+
operation: Unsafe(schemaRef(SignerOperationSchema)),
|
|
5263
|
+
approvalUrl: String$1(),
|
|
5264
|
+
expiresAt: String$1()
|
|
5265
|
+
}, {
|
|
5266
|
+
$id: "SignerCeremony",
|
|
5267
|
+
additionalProperties: false
|
|
5268
|
+
});
|
|
5269
|
+
var SignerPendingResultSchema = _Object_({
|
|
5270
|
+
version: Literal(1),
|
|
5271
|
+
status: Literal("pending"),
|
|
5272
|
+
operation: Unsafe(schemaRef(SignerOperationSchema))
|
|
5273
|
+
}, {
|
|
5274
|
+
$id: "SignerPendingResult",
|
|
5275
|
+
additionalProperties: false
|
|
5276
|
+
});
|
|
5277
|
+
var SignerEnrollmentResultSchema = _Object_({
|
|
5278
|
+
version: Literal(1),
|
|
5279
|
+
status: Literal("completed"),
|
|
5280
|
+
operation: Literal("credential-enrollment"),
|
|
5281
|
+
publicMaterial: Unsafe(schemaRef(SignerPreviewSignPublicMaterialSchema))
|
|
5282
|
+
}, {
|
|
5283
|
+
$id: "SignerEnrollmentResult",
|
|
5284
|
+
additionalProperties: false
|
|
5285
|
+
});
|
|
5286
|
+
var SignerReceiptSchema = PreviewSignReceiptValueSchema;
|
|
5287
|
+
var SignerSignatureResultSchema = _Object_({
|
|
5288
|
+
version: Literal(1),
|
|
5289
|
+
status: Literal("completed"),
|
|
5290
|
+
operation: Unsafe(schemaRef(SignerChallengeOperationSchema)),
|
|
5291
|
+
receipt: Unsafe(schemaRef(SignerReceiptSchema))
|
|
5292
|
+
}, {
|
|
5293
|
+
$id: "SignerSignatureResult",
|
|
5294
|
+
additionalProperties: false
|
|
5295
|
+
});
|
|
5296
|
+
var SignerFailedResultSchema = _Object_({
|
|
5297
|
+
version: Literal(1),
|
|
5298
|
+
status: Literal("failed"),
|
|
5299
|
+
operation: Unsafe(schemaRef(SignerOperationSchema)),
|
|
5300
|
+
code: String$1(),
|
|
5301
|
+
message: String$1()
|
|
5302
|
+
}, {
|
|
5303
|
+
$id: "SignerFailedResult",
|
|
5304
|
+
additionalProperties: false
|
|
5305
|
+
});
|
|
5306
|
+
var SignerCeremonyResultSchema = Union([
|
|
5307
|
+
Unsafe(schemaRef(SignerPendingResultSchema)),
|
|
5308
|
+
Unsafe(schemaRef(SignerEnrollmentResultSchema)),
|
|
5309
|
+
Unsafe(schemaRef(SignerSignatureResultSchema)),
|
|
5310
|
+
Unsafe(schemaRef(SignerFailedResultSchema))
|
|
5311
|
+
], { $id: "SignerCeremonyResult" });
|
|
5312
|
+
({ ...previewSignSchemaContext }), schemaId(SignerUuidSchema), schemaId(SignerOperationSchema), schemaId(SignerProblemSchema), schemaId(SignerCeremonyParamsSchema), schemaId(SignerSessionSchema), schemaId(SignerEnrollmentCeremonyRequestSchema), schemaId(SignerChallengeCeremonyRequestSchema), schemaId(SignerCeremonyRequestSchema), schemaId(SignerCeremonySchema), schemaId(SignerPendingResultSchema), schemaId(SignerEnrollmentResultSchema), schemaId(SignerSignatureResultSchema), schemaId(SignerFailedResultSchema), schemaId(SignerCeremonyResultSchema);
|
|
5313
|
+
//#endregion
|
|
5314
|
+
//#region ../../libs/models/src/tool-enforcement.ts
|
|
5315
|
+
var TOOL_ENFORCEMENT_VALUES = [
|
|
5316
|
+
"off",
|
|
5317
|
+
"watch",
|
|
5318
|
+
"enforce"
|
|
5319
|
+
];
|
|
5320
|
+
var ToolEnforcementSchema = Union([
|
|
5321
|
+
Literal(TOOL_ENFORCEMENT_VALUES[0]),
|
|
5322
|
+
Literal(TOOL_ENFORCEMENT_VALUES[1]),
|
|
5323
|
+
Literal(TOOL_ENFORCEMENT_VALUES[2])
|
|
5324
|
+
], { description: "Runtime tool-policy enforcement mode: off (inert), watch (audit only), enforce (block disallowed tools, fail-closed)." });
|
|
5325
|
+
//#endregion
|
|
4457
5326
|
//#region ../../libs/tasks/src/runtime-profiles.ts
|
|
4458
5327
|
var RuntimeProfileName = String$1({
|
|
4459
5328
|
minLength: 1,
|
|
@@ -4480,11 +5349,7 @@ var RuntimeProfileWorkspaceMode = Union([
|
|
|
4480
5349
|
* `off` (inert), `watch` (audit only), `enforce` (block disallowed tools,
|
|
4481
5350
|
* fail-closed). Read by the daemon via `GET /runtime-profiles/:id/allowed-tools`.
|
|
4482
5351
|
*/
|
|
4483
|
-
var RuntimeProfileToolEnforcement =
|
|
4484
|
-
Literal("off"),
|
|
4485
|
-
Literal("watch"),
|
|
4486
|
-
Literal("enforce")
|
|
4487
|
-
]);
|
|
5352
|
+
var RuntimeProfileToolEnforcement = ToolEnforcementSchema;
|
|
4488
5353
|
var RuntimeProfileAllowedWorkspaceModes = _Array_(RuntimeProfileWorkspaceMode, {
|
|
4489
5354
|
minItems: 1,
|
|
4490
5355
|
maxItems: 3,
|
|
@@ -6537,7 +7402,7 @@ var BUILT_IN_TASK_TYPES = {
|
|
|
6537
7402
|
outputKind: "artifact",
|
|
6538
7403
|
resumable: true,
|
|
6539
7404
|
workspaceMode: "shared_mount",
|
|
6540
|
-
workspaceScope: "
|
|
7405
|
+
workspaceScope: "attempt",
|
|
6541
7406
|
sessionScope: "correlation",
|
|
6542
7407
|
acceptsInputWorkspaceOverride: true,
|
|
6543
7408
|
requiresReferences: false,
|
|
@@ -9880,6 +10745,11 @@ function createGhCliClient() {
|
|
|
9880
10745
|
};
|
|
9881
10746
|
}
|
|
9882
10747
|
//#endregion
|
|
10748
|
+
//#region src/lib/daemon-slot-identity.ts
|
|
10749
|
+
function createRuntimeInstanceId() {
|
|
10750
|
+
return randomUUID();
|
|
10751
|
+
}
|
|
10752
|
+
//#endregion
|
|
9883
10753
|
//#region src/lib/session-files.ts
|
|
9884
10754
|
function resolveLatestPiSessionPath(sessionDir) {
|
|
9885
10755
|
try {
|
|
@@ -9950,10 +10820,10 @@ function slugifySessionComponent(input) {
|
|
|
9950
10820
|
}
|
|
9951
10821
|
//#endregion
|
|
9952
10822
|
//#region src/lib/task-execution-plan.ts
|
|
9953
|
-
function buildDaemonTaskExecutionPlan(task, stateDirs, identity, warmSessionTtlSec, runtimeProfileWorkspacePolicy = {}) {
|
|
10823
|
+
function buildDaemonTaskExecutionPlan(task, stateDirs, identity, warmSessionTtlSec, runtimeProfileWorkspacePolicy = {}, attemptN) {
|
|
9954
10824
|
const descriptor = deriveTaskSessionDescriptor(task);
|
|
9955
10825
|
const workspaceMode = resolveTaskWorkspaceMode(task, descriptor.policy, runtimeProfileWorkspacePolicy);
|
|
9956
|
-
const slotKey = warmSessionTtlSec > 0 ? descriptor.sessionKey : null;
|
|
10826
|
+
const slotKey = warmSessionTtlSec > 0 && descriptor.sessionKey ? buildRuntimeSlotKey(descriptor.sessionKey, identity.runtimeInstanceId) : null;
|
|
9957
10827
|
const workspaceScope = slotKey !== null ? descriptor.policy.workspaceScope : "attempt";
|
|
9958
10828
|
const slotId = slotKey ? buildDaemonSlotId(identity, slotKey) : null;
|
|
9959
10829
|
const sessionDir = slotId ? `${stateDirs.piSessionsDir}/${encodeURIComponent(slotId)}` : null;
|
|
@@ -9961,7 +10831,8 @@ function buildDaemonTaskExecutionPlan(task, stateDirs, identity, warmSessionTtlS
|
|
|
9961
10831
|
const workspaceId = workspaceMode !== "shared_mount" ? resolveTaskWorkspaceId(task, {
|
|
9962
10832
|
sessionKey: slotId,
|
|
9963
10833
|
workspaceScope,
|
|
9964
|
-
sessionPersistence: sessionDir ? { sessionDir } : null
|
|
10834
|
+
sessionPersistence: sessionDir ? { sessionDir } : null,
|
|
10835
|
+
attemptN
|
|
9965
10836
|
}) : null;
|
|
9966
10837
|
return {
|
|
9967
10838
|
descriptor,
|
|
@@ -9985,6 +10856,12 @@ function buildDaemonSlotId(identity, slotKey) {
|
|
|
9985
10856
|
slotKey
|
|
9986
10857
|
].join(":");
|
|
9987
10858
|
}
|
|
10859
|
+
function buildRuntimeSlotKey(logicalSessionKey, runtimeInstanceId) {
|
|
10860
|
+
return runtimeInstanceId ? `${logicalSessionKey}:worker:${slugSlotIdentityComponent(runtimeInstanceId)}` : logicalSessionKey;
|
|
10861
|
+
}
|
|
10862
|
+
function runtimeSlotKeyBelongsToInstance(slotKey, runtimeInstanceId) {
|
|
10863
|
+
return slotKey.endsWith(`:worker:${slugSlotIdentityComponent(runtimeInstanceId)}`);
|
|
10864
|
+
}
|
|
9988
10865
|
function slugSlotIdentityComponent(input) {
|
|
9989
10866
|
return slugifyAsciiLower(input.trim(), 64, [
|
|
9990
10867
|
".",
|
|
@@ -10039,7 +10916,7 @@ function toDaemonWorkspaceMode(mode) {
|
|
|
10039
10916
|
}
|
|
10040
10917
|
function resolveTaskWorkspaceId(task, executionPlan) {
|
|
10041
10918
|
if (executionPlan.workspaceScope === "session" && executionPlan.sessionKey !== null) return `session-${encodeURIComponent(executionPlan.sessionKey)}`;
|
|
10042
|
-
return `task-${task.id}`;
|
|
10919
|
+
return executionPlan.attemptN ? `daemon-task-${task.id}-attempt-${executionPlan.attemptN}` : `task-${task.id}`;
|
|
10043
10920
|
}
|
|
10044
10921
|
//#endregion
|
|
10045
10922
|
//#region src/lib/execution-plan-cache.ts
|
|
@@ -10058,7 +10935,7 @@ function createExecutionPlanCache(args) {
|
|
|
10058
10935
|
const key = buildClaimedTaskKey(claimedTask);
|
|
10059
10936
|
const existing = cache.get(key);
|
|
10060
10937
|
if (existing) return existing;
|
|
10061
|
-
const plan = await maybeAttachWarmSlotContext(claimedTask, buildDaemonTaskExecutionPlan(claimedTask.task, args.stateDirs, args.slotIdentity, args.warmSessionTtlSec, args.workspacePolicy), args.stateDirs, args.slotRegistry, runtimeSessionStore, sourceAttemptResolver);
|
|
10938
|
+
const plan = await maybeAttachWarmSlotContext(claimedTask, buildDaemonTaskExecutionPlan(claimedTask.task, args.stateDirs, args.slotIdentity, args.warmSessionTtlSec, args.workspacePolicy, claimedTask.attemptN), args.stateDirs, args.slotRegistry, runtimeSessionStore, sourceAttemptResolver);
|
|
10062
10939
|
assertPlanAllowedByWorkspacePolicy(plan, args.workspacePolicy);
|
|
10063
10940
|
cache.set(key, plan);
|
|
10064
10941
|
return plan;
|
|
@@ -10125,14 +11002,13 @@ async function resolveWarmSlot(slotRegistry, runtimeSessionStore, teamId, source
|
|
|
10125
11002
|
return {
|
|
10126
11003
|
kind: "found",
|
|
10127
11004
|
producerSlot: producerContext,
|
|
10128
|
-
sessionPath: sourceSessionPath
|
|
10129
|
-
workspacePath: resolveProducerWorkspaceCopySource(producerContext, stateDirs)
|
|
11005
|
+
sessionPath: sourceSessionPath
|
|
10130
11006
|
};
|
|
10131
11007
|
}
|
|
10132
11008
|
async function maybeAttachWarmSlotContext(claimedTask, basePlan, stateDirs, slotRegistry, runtimeSessionStore, sourceAttemptResolver) {
|
|
10133
11009
|
if (claimedTask.task.taskType === "freeform") {
|
|
10134
11010
|
const continueFrom = claimedTask.task.input.continueFrom;
|
|
10135
|
-
if (!continueFrom) return basePlan;
|
|
11011
|
+
if (!continueFrom) return maybeAttachRetrySession(claimedTask, basePlan, stateDirs, slotRegistry, runtimeSessionStore);
|
|
10136
11012
|
const resolution = await resolveWarmSlot(slotRegistry, runtimeSessionStore, claimedTask.task.teamId, continueFrom.taskId, continueFrom.attemptN, stateDirs);
|
|
10137
11013
|
if (resolution.kind === "missing") throw new ProducerContextResolutionError(`Continuation source task ${continueFrom.taskId} attempt ${continueFrom.attemptN} has no local runtime slot or durable runtime session — claim affinity filter should have prevented this claim`);
|
|
10138
11014
|
if (resolution.kind === "no-session-path") throw new ProducerContextResolutionError(`Continuation source attempt ${continueFrom.taskId}/${continueFrom.attemptN} has no persisted Pi session path`);
|
|
@@ -10164,7 +11040,7 @@ async function maybeAttachWarmSlotContext(claimedTask, basePlan, stateDirs, slot
|
|
|
10164
11040
|
return {
|
|
10165
11041
|
...basePlan,
|
|
10166
11042
|
workspaceMode: "dedicated_worktree",
|
|
10167
|
-
workspaceId: recoveredBranch ?
|
|
11043
|
+
workspaceId: recoveredBranch ? buildAttemptWorkspaceId(claimedTask) : null,
|
|
10168
11044
|
worktreeBranch: recoveredBranch,
|
|
10169
11045
|
sessionPersistence: {
|
|
10170
11046
|
sessionDir,
|
|
@@ -10193,7 +11069,7 @@ async function maybeAttachWarmSlotContext(claimedTask, basePlan, stateDirs, slot
|
|
|
10193
11069
|
return {
|
|
10194
11070
|
...basePlan,
|
|
10195
11071
|
workspaceMode: "dedicated_worktree",
|
|
10196
|
-
workspaceId:
|
|
11072
|
+
workspaceId: parentBranch ? buildAttemptWorkspaceId(claimedTask) : null,
|
|
10197
11073
|
worktreeBranch: parentBranch,
|
|
10198
11074
|
sessionPersistence: {
|
|
10199
11075
|
sessionDir,
|
|
@@ -10215,7 +11091,7 @@ async function maybeAttachWarmSlotContext(claimedTask, basePlan, stateDirs, slot
|
|
|
10215
11091
|
worktreeBranch: null,
|
|
10216
11092
|
workspaceKind: "scratch",
|
|
10217
11093
|
workspaceSeed: {
|
|
10218
|
-
copyFromPath: resolution.
|
|
11094
|
+
copyFromPath: resolveProducerWorkspaceCopySource(resolution.producerSlot, stateDirs),
|
|
10219
11095
|
source: "producer"
|
|
10220
11096
|
},
|
|
10221
11097
|
sessionPersistence: {
|
|
@@ -10224,6 +11100,25 @@ async function maybeAttachWarmSlotContext(claimedTask, basePlan, stateDirs, slot
|
|
|
10224
11100
|
}
|
|
10225
11101
|
};
|
|
10226
11102
|
}
|
|
11103
|
+
function buildAttemptWorkspaceId(claimedTask) {
|
|
11104
|
+
return `daemon-task-${claimedTask.task.id}-attempt-${claimedTask.attemptN}`;
|
|
11105
|
+
}
|
|
11106
|
+
async function maybeAttachRetrySession(claimedTask, basePlan, stateDirs, slotRegistry, runtimeSessionStore) {
|
|
11107
|
+
if (claimedTask.attemptN <= 1 || !basePlan.sessionPersistence?.sessionDir) return basePlan;
|
|
11108
|
+
const resolution = await resolveWarmSlot(slotRegistry, runtimeSessionStore, claimedTask.task.teamId, claimedTask.task.id, claimedTask.attemptN - 1, stateDirs);
|
|
11109
|
+
if (resolution.kind === "missing" || resolution.kind === "no-session-path") return basePlan;
|
|
11110
|
+
const sourceSessionDir = dirname(resolution.sessionPath);
|
|
11111
|
+
const targetSessionDir = basePlan.sessionPersistence.sessionDir;
|
|
11112
|
+
if (sourceSessionDir === targetSessionDir) return basePlan;
|
|
11113
|
+
return {
|
|
11114
|
+
...basePlan,
|
|
11115
|
+
worktreeBranch: basePlan.workspaceMode === "dedicated_worktree" && resolution.kind === "found" ? resolution.producerSlot.workspace?.worktreeBranch ?? basePlan.worktreeBranch : basePlan.worktreeBranch,
|
|
11116
|
+
sessionPersistence: {
|
|
11117
|
+
sessionDir: targetSessionDir,
|
|
11118
|
+
forkFromSessionPath: resolution.sessionPath
|
|
11119
|
+
}
|
|
11120
|
+
};
|
|
11121
|
+
}
|
|
10227
11122
|
function buildForkBranch(parentBranch, childTaskId, childAttemptN) {
|
|
10228
11123
|
return `${parentBranch}-fork-${childTaskId.slice(0, 8)}-${childAttemptN}`;
|
|
10229
11124
|
}
|
|
@@ -10267,6 +11162,7 @@ var RETRYABLE_CODES = new Set([
|
|
|
10267
11162
|
]);
|
|
10268
11163
|
var NON_RETRYABLE_CODES = new Set([
|
|
10269
11164
|
"bad_api_key",
|
|
11165
|
+
"executor_threw",
|
|
10270
11166
|
"invalid_api_key",
|
|
10271
11167
|
"invalid_model",
|
|
10272
11168
|
"max_turns_exceeded",
|
|
@@ -10309,17 +11205,18 @@ var NON_RETRYABLE_MESSAGE_PATTERNS = [
|
|
|
10309
11205
|
/\bmax (?:turn|bash)/i
|
|
10310
11206
|
];
|
|
10311
11207
|
async function classifyAttemptFailure(input) {
|
|
10312
|
-
|
|
10313
|
-
|
|
11208
|
+
const deterministic = classifyDeterministically(input.error);
|
|
11209
|
+
if (input.remainingAttempts !== null && input.remainingAttempts !== void 0 && input.remainingAttempts <= 0) {
|
|
11210
|
+
const deterministicReason = deterministic === "ambiguous" ? "" : ` Deterministic policy classified the failure as ${deterministic}.`;
|
|
11211
|
+
return {
|
|
10314
11212
|
error: withRetryInfo(input.error, {
|
|
10315
11213
|
retryable: false,
|
|
10316
11214
|
source: "attempts_exhausted",
|
|
10317
|
-
reason: `Attempt budget exhausted at attempt ${input.attemptN}${input.maxAttempts ? ` of ${input.maxAttempts}` : ""}
|
|
11215
|
+
reason: `Attempt budget exhausted at attempt ${input.attemptN}${input.maxAttempts ? ` of ${input.maxAttempts}` : ""}.${deterministicReason}`
|
|
10318
11216
|
}),
|
|
10319
11217
|
source: "attempts_exhausted"
|
|
10320
11218
|
};
|
|
10321
11219
|
}
|
|
10322
|
-
const deterministic = classifyDeterministically(input.error);
|
|
10323
11220
|
if (deterministic !== "ambiguous") {
|
|
10324
11221
|
const retryable = deterministic === "retryable";
|
|
10325
11222
|
const source = input.error.retryable === retryable ? "explicit" : "deterministic";
|
|
@@ -10895,6 +11792,269 @@ function createRuntimeProfileRetryTriage(options) {
|
|
|
10895
11792
|
});
|
|
10896
11793
|
}
|
|
10897
11794
|
//#endregion
|
|
11795
|
+
//#region src/lib/runtime-resource-reaper.ts
|
|
11796
|
+
var RUNTIME_SLOT_PAGE_LIMIT = 200;
|
|
11797
|
+
var ATTEMPT_LOOKUP_CONCURRENCY = 8;
|
|
11798
|
+
var TERMINAL_ATTEMPT_STATUSES = new Set([
|
|
11799
|
+
"completed",
|
|
11800
|
+
"failed",
|
|
11801
|
+
"cancelled",
|
|
11802
|
+
"aborted",
|
|
11803
|
+
"timed_out"
|
|
11804
|
+
]);
|
|
11805
|
+
/**
|
|
11806
|
+
* Reap daemon-owned local resources whose runtime slot is no longer usable.
|
|
11807
|
+
* The destructive path is deliberately conservative: uncertainty about slot
|
|
11808
|
+
* ownership, attempt state, listing completeness, or real filesystem
|
|
11809
|
+
* containment retains resources rather than risking another daemon's data.
|
|
11810
|
+
*/
|
|
11811
|
+
async function reapRuntimeSlotResources(deps, input) {
|
|
11812
|
+
const now = input.now ?? Date.now();
|
|
11813
|
+
const [activePage, idlePage] = await Promise.all([listOwnedSlots(deps.runtimeSlotStore, input, "active"), listOwnedSlots(deps.runtimeSlotStore, input, "idle")]);
|
|
11814
|
+
const active = activePage.items;
|
|
11815
|
+
const idle = idlePage.items;
|
|
11816
|
+
const slots = [...active, ...idle];
|
|
11817
|
+
const result = {
|
|
11818
|
+
failed: 0,
|
|
11819
|
+
failures: [],
|
|
11820
|
+
removedSessions: 0,
|
|
11821
|
+
removedWorkspaces: 0,
|
|
11822
|
+
scanned: slots.length,
|
|
11823
|
+
truncated: activePage.truncated || idlePage.truncated,
|
|
11824
|
+
unsafePathDetails: [],
|
|
11825
|
+
unsafePaths: 0
|
|
11826
|
+
};
|
|
11827
|
+
const reaped = new Set(idle.filter((item) => item.slot.expiresAtMs <= now).map((item) => item.slot.id));
|
|
11828
|
+
for (const slotId of await findTerminalActiveSlotIds(deps, active, result)) reaped.add(slotId);
|
|
11829
|
+
const retainedSessionDirs = new Set(slots.filter((item) => !reaped.has(item.slot.id)).flatMap((item) => item.session?.sessionDir ? [resolve(item.session.sessionDir)] : []));
|
|
11830
|
+
const retainedWorkspacePaths = new Set(slots.filter((item) => !reaped.has(item.slot.id)).flatMap((item) => item.workspace?.worktreePath ? [resolve(item.workspace.worktreePath)] : []));
|
|
11831
|
+
const worktrees = input.mainWorktree ? await listRegisteredWorktrees(input.mainWorktree) : {
|
|
11832
|
+
kind: "ready",
|
|
11833
|
+
paths: /* @__PURE__ */ new Set()
|
|
11834
|
+
};
|
|
11835
|
+
for (const item of slots) {
|
|
11836
|
+
if (!reaped.has(item.slot.id)) continue;
|
|
11837
|
+
if (!await slotStillQualifiesForReaping(deps, input, item, now, result)) continue;
|
|
11838
|
+
const sessionDir = item.session?.sessionDir;
|
|
11839
|
+
if (sessionDir && !retainedSessionDirs.has(resolve(sessionDir)) && existsSync(sessionDir)) if (!isRealPathInsideRoot(sessionDir, input.sessionRootDir)) recordUnsafePath(deps, result, item.slot.id, sessionDir, input.sessionRootDir);
|
|
11840
|
+
else try {
|
|
11841
|
+
rmSync(sessionDir, {
|
|
11842
|
+
force: true,
|
|
11843
|
+
recursive: true
|
|
11844
|
+
});
|
|
11845
|
+
result.removedSessions++;
|
|
11846
|
+
} catch (err) {
|
|
11847
|
+
recordFailure(deps, result, item.slot.id, sessionDir, input.sessionRootDir, err);
|
|
11848
|
+
}
|
|
11849
|
+
const workspacePath = item.workspace?.worktreePath;
|
|
11850
|
+
if (!workspacePath || retainedWorkspacePaths.has(resolve(workspacePath))) continue;
|
|
11851
|
+
const workspaceRoot = item.workspace?.kind === "scratch" ? input.scratchRootDir : input.mainWorktree ? resolve(input.mainWorktree, ".worktrees") : null;
|
|
11852
|
+
if (!workspaceRoot) {
|
|
11853
|
+
recordUnsafePath(deps, result, item.slot.id, workspacePath, null);
|
|
11854
|
+
continue;
|
|
11855
|
+
}
|
|
11856
|
+
await removeWorkspace(deps, result, worktrees, input.mainWorktree, item.slot.id, workspacePath, workspaceRoot, item.workspace?.kind === "scratch");
|
|
11857
|
+
}
|
|
11858
|
+
if (!result.truncated) await reapLegacyOrphanWorktrees(deps, input, worktrees, retainedSessionDirs, retainedWorkspacePaths, result);
|
|
11859
|
+
return result;
|
|
11860
|
+
}
|
|
11861
|
+
async function listOwnedSlots(store, input, state) {
|
|
11862
|
+
const listed = await store.listSlots({
|
|
11863
|
+
agentName: input.agentName,
|
|
11864
|
+
limit: RUNTIME_SLOT_PAGE_LIMIT,
|
|
11865
|
+
runtimeProfileId: input.runtimeProfileId,
|
|
11866
|
+
state,
|
|
11867
|
+
teamId: input.teamId
|
|
11868
|
+
});
|
|
11869
|
+
return {
|
|
11870
|
+
items: listed.filter((item) => runtimeSlotKeyBelongsToInstance(item.slot.slotKey, input.runtimeInstanceId)),
|
|
11871
|
+
truncated: listed.length === RUNTIME_SLOT_PAGE_LIMIT
|
|
11872
|
+
};
|
|
11873
|
+
}
|
|
11874
|
+
async function findTerminalActiveSlotIds(deps, active, result) {
|
|
11875
|
+
const byTask = /* @__PURE__ */ new Map();
|
|
11876
|
+
for (const item of active) {
|
|
11877
|
+
const taskSlots = byTask.get(item.slot.lastTaskId) ?? [];
|
|
11878
|
+
taskSlots.push(item);
|
|
11879
|
+
byTask.set(item.slot.lastTaskId, taskSlots);
|
|
11880
|
+
}
|
|
11881
|
+
const terminal = /* @__PURE__ */ new Set();
|
|
11882
|
+
await mapWithConcurrency([...byTask.entries()], ATTEMPT_LOOKUP_CONCURRENCY, async ([taskId, taskSlots]) => {
|
|
11883
|
+
let attempts;
|
|
11884
|
+
try {
|
|
11885
|
+
attempts = await deps.taskReader.listAttempts(taskId);
|
|
11886
|
+
} catch (err) {
|
|
11887
|
+
recordFailure(deps, result, null, `task:${taskId}`, null, err);
|
|
11888
|
+
return;
|
|
11889
|
+
}
|
|
11890
|
+
for (const item of taskSlots) {
|
|
11891
|
+
const attempt = attempts.find((candidate) => candidate.attemptN === item.slot.lastAttemptN);
|
|
11892
|
+
if (attempt && TERMINAL_ATTEMPT_STATUSES.has(attempt.status)) terminal.add(item.slot.id);
|
|
11893
|
+
}
|
|
11894
|
+
});
|
|
11895
|
+
return terminal;
|
|
11896
|
+
}
|
|
11897
|
+
async function slotStillQualifiesForReaping(deps, input, original, now, result) {
|
|
11898
|
+
let page;
|
|
11899
|
+
try {
|
|
11900
|
+
page = await listOwnedSlots(deps.runtimeSlotStore, input, original.slot.state);
|
|
11901
|
+
} catch (err) {
|
|
11902
|
+
recordFailure(deps, result, original.slot.id, `slot:${original.slot.id}`, null, err);
|
|
11903
|
+
return false;
|
|
11904
|
+
}
|
|
11905
|
+
const current = page.items.find((candidate) => candidate.slot.id === original.slot.id);
|
|
11906
|
+
if (!current) return false;
|
|
11907
|
+
if (current.slot.lastTaskId !== original.slot.lastTaskId || current.slot.lastAttemptN !== original.slot.lastAttemptN) return false;
|
|
11908
|
+
return current.slot.state === "active" || current.slot.state === "idle" && current.slot.expiresAtMs <= now;
|
|
11909
|
+
}
|
|
11910
|
+
async function reapLegacyOrphanWorktrees(deps, input, worktrees, retainedSessionDirs, retainedWorkspacePaths, result) {
|
|
11911
|
+
if (!input.mainWorktree) return;
|
|
11912
|
+
const workspaceRoot = resolve(input.mainWorktree, ".worktrees");
|
|
11913
|
+
if (!existsSync(workspaceRoot)) return;
|
|
11914
|
+
let entries;
|
|
11915
|
+
try {
|
|
11916
|
+
entries = readdirSync(workspaceRoot, { withFileTypes: true });
|
|
11917
|
+
} catch (err) {
|
|
11918
|
+
recordFailure(deps, result, null, workspaceRoot, workspaceRoot, err);
|
|
11919
|
+
return;
|
|
11920
|
+
}
|
|
11921
|
+
for (const entry of entries) {
|
|
11922
|
+
if (!entry.isDirectory() || !entry.name.startsWith("session-agent%3A")) continue;
|
|
11923
|
+
const workspacePath = resolve(workspaceRoot, entry.name);
|
|
11924
|
+
if (retainedWorkspacePaths.has(workspacePath)) continue;
|
|
11925
|
+
const sessionDir = resolve(input.sessionRootDir, entry.name.slice(8));
|
|
11926
|
+
if (retainedSessionDirs.has(sessionDir) || existsSync(sessionDir)) continue;
|
|
11927
|
+
await removeWorkspace(deps, result, worktrees, input.mainWorktree, null, workspacePath, workspaceRoot, false);
|
|
11928
|
+
}
|
|
11929
|
+
}
|
|
11930
|
+
async function removeWorkspace(deps, result, worktrees, mainWorktree, slotId, workspacePath, workspaceRoot, scratch) {
|
|
11931
|
+
if (!existsSync(workspacePath)) return;
|
|
11932
|
+
if (!isRealPathInsideRoot(workspacePath, workspaceRoot)) {
|
|
11933
|
+
recordUnsafePath(deps, result, slotId, workspacePath, workspaceRoot);
|
|
11934
|
+
return;
|
|
11935
|
+
}
|
|
11936
|
+
if (scratch || !mainWorktree) {
|
|
11937
|
+
try {
|
|
11938
|
+
rmSync(workspacePath, {
|
|
11939
|
+
force: true,
|
|
11940
|
+
recursive: true
|
|
11941
|
+
});
|
|
11942
|
+
result.removedWorkspaces++;
|
|
11943
|
+
} catch (err) {
|
|
11944
|
+
recordFailure(deps, result, slotId, workspacePath, workspaceRoot, err);
|
|
11945
|
+
}
|
|
11946
|
+
return;
|
|
11947
|
+
}
|
|
11948
|
+
if (worktrees.kind === "unavailable") {
|
|
11949
|
+
recordFailure(deps, result, slotId, workspacePath, workspaceRoot, new Error(worktrees.reason));
|
|
11950
|
+
return;
|
|
11951
|
+
}
|
|
11952
|
+
try {
|
|
11953
|
+
const canonical = realpathSync(workspacePath);
|
|
11954
|
+
if (worktrees.paths.has(canonical)) {
|
|
11955
|
+
await execFileText("git", [
|
|
11956
|
+
"-C",
|
|
11957
|
+
mainWorktree,
|
|
11958
|
+
"worktree",
|
|
11959
|
+
"remove",
|
|
11960
|
+
"--force",
|
|
11961
|
+
workspacePath
|
|
11962
|
+
]);
|
|
11963
|
+
worktrees.paths.delete(canonical);
|
|
11964
|
+
} else rmSync(workspacePath, {
|
|
11965
|
+
force: true,
|
|
11966
|
+
recursive: true
|
|
11967
|
+
});
|
|
11968
|
+
result.removedWorkspaces++;
|
|
11969
|
+
} catch (err) {
|
|
11970
|
+
recordFailure(deps, result, slotId, workspacePath, workspaceRoot, err);
|
|
11971
|
+
}
|
|
11972
|
+
}
|
|
11973
|
+
async function listRegisteredWorktrees(mainWorktree) {
|
|
11974
|
+
try {
|
|
11975
|
+
const list = await execFileText("git", [
|
|
11976
|
+
"-C",
|
|
11977
|
+
mainWorktree,
|
|
11978
|
+
"worktree",
|
|
11979
|
+
"list",
|
|
11980
|
+
"--porcelain"
|
|
11981
|
+
]);
|
|
11982
|
+
return {
|
|
11983
|
+
kind: "ready",
|
|
11984
|
+
paths: new Set(list.split("\n").filter((line) => line.startsWith("worktree ")).map((line) => canonicalPath(line.slice(9))))
|
|
11985
|
+
};
|
|
11986
|
+
} catch (err) {
|
|
11987
|
+
return {
|
|
11988
|
+
kind: "unavailable",
|
|
11989
|
+
reason: errorMessage(err)
|
|
11990
|
+
};
|
|
11991
|
+
}
|
|
11992
|
+
}
|
|
11993
|
+
function isRealPathInsideRoot(path, root) {
|
|
11994
|
+
try {
|
|
11995
|
+
return isResolvedPathInsideRoot$1(realpathSync(path), realpathSync(root));
|
|
11996
|
+
} catch {
|
|
11997
|
+
return false;
|
|
11998
|
+
}
|
|
11999
|
+
}
|
|
12000
|
+
function isResolvedPathInsideRoot$1(path, root) {
|
|
12001
|
+
const rel = relative(root, path);
|
|
12002
|
+
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
12003
|
+
}
|
|
12004
|
+
function canonicalPath(path) {
|
|
12005
|
+
try {
|
|
12006
|
+
return realpathSync(path);
|
|
12007
|
+
} catch {
|
|
12008
|
+
return resolve(path);
|
|
12009
|
+
}
|
|
12010
|
+
}
|
|
12011
|
+
function recordUnsafePath(deps, result, slotId, path, root) {
|
|
12012
|
+
const issue = {
|
|
12013
|
+
kind: "unsafe_path",
|
|
12014
|
+
path,
|
|
12015
|
+
reason: root === null ? "No daemon-owned root was available for this workspace." : "Candidate or root could not be resolved inside the daemon-owned root.",
|
|
12016
|
+
root,
|
|
12017
|
+
slotId
|
|
12018
|
+
};
|
|
12019
|
+
result.unsafePaths++;
|
|
12020
|
+
result.unsafePathDetails.push(issue);
|
|
12021
|
+
emitIssue(deps, issue);
|
|
12022
|
+
}
|
|
12023
|
+
function recordFailure(deps, result, slotId, path, root, err) {
|
|
12024
|
+
const issue = {
|
|
12025
|
+
kind: "failure",
|
|
12026
|
+
path,
|
|
12027
|
+
reason: errorMessage(err),
|
|
12028
|
+
root,
|
|
12029
|
+
slotId
|
|
12030
|
+
};
|
|
12031
|
+
result.failed++;
|
|
12032
|
+
result.failures.push(issue);
|
|
12033
|
+
emitIssue(deps, issue);
|
|
12034
|
+
}
|
|
12035
|
+
function emitIssue(deps, issue) {
|
|
12036
|
+
try {
|
|
12037
|
+
deps.onIssue?.(issue);
|
|
12038
|
+
} catch {}
|
|
12039
|
+
}
|
|
12040
|
+
function errorMessage(err) {
|
|
12041
|
+
return err instanceof Error ? err.message : String(err);
|
|
12042
|
+
}
|
|
12043
|
+
async function execFileText(file, args) {
|
|
12044
|
+
return new Promise((resolvePromise, reject) => {
|
|
12045
|
+
execFile(file, args, {
|
|
12046
|
+
encoding: "utf8",
|
|
12047
|
+
maxBuffer: 10 * 1024 * 1024
|
|
12048
|
+
}, (err, stdout) => {
|
|
12049
|
+
if (err) reject(err instanceof Error ? err : /* @__PURE__ */ new Error("Child process failed without an Error instance."));
|
|
12050
|
+
else resolvePromise(stdout);
|
|
12051
|
+
});
|
|
12052
|
+
});
|
|
12053
|
+
}
|
|
12054
|
+
async function mapWithConcurrency(items, concurrency, worker) {
|
|
12055
|
+
for (let index = 0; index < items.length; index += concurrency) await Promise.all(items.slice(index, index + concurrency).map(worker));
|
|
12056
|
+
}
|
|
12057
|
+
//#endregion
|
|
10898
12058
|
//#region src/lib/runtime-sessions.ts
|
|
10899
12059
|
function resolveRuntimeSessionKind(claimedTask) {
|
|
10900
12060
|
const continueFrom = resolveContinueFrom(claimedTask);
|
|
@@ -11031,6 +12191,8 @@ function createApiRuntimeSlotStore(args) {
|
|
|
11031
12191
|
lastAttemptN: resolved.slot.lastAttemptN,
|
|
11032
12192
|
lastTaskId: resolved.slot.lastTaskId,
|
|
11033
12193
|
runtimeProfileId: resolved.slot.runtimeProfileId,
|
|
12194
|
+
slotKey: resolved.slot.slotKey,
|
|
12195
|
+
state: resolved.slot.state,
|
|
11034
12196
|
taskType: resolved.slot.taskType
|
|
11035
12197
|
},
|
|
11036
12198
|
session: resolved.slot.sessionDir ? {
|
|
@@ -11202,12 +12364,13 @@ async function runPolling(opts) {
|
|
|
11202
12364
|
agent: ctx.agent,
|
|
11203
12365
|
profiles: profileValues,
|
|
11204
12366
|
teamId,
|
|
11205
|
-
cwd:
|
|
12367
|
+
cwd: ctx.agentRootDir
|
|
11206
12368
|
});
|
|
11207
12369
|
for (const profile of profiles) validateRuntimeProfilePrerequisites(profile, cfg.profilePrerequisiteEnv, cfg.profilePrerequisitePath);
|
|
11208
12370
|
const slotRegistry = createApiRuntimeSlotStore({ agent: ctx.agent });
|
|
11209
12371
|
const runtimeSessionStore = createApiRuntimeSessionStore({ agent: ctx.agent });
|
|
11210
12372
|
const sourceAttemptResolver = createApiSourceAttemptResolver({ agent: ctx.agent });
|
|
12373
|
+
const runtimeInstanceId = createRuntimeInstanceId();
|
|
11211
12374
|
const runtimes = /* @__PURE__ */ new Map();
|
|
11212
12375
|
for (const profile of profiles) {
|
|
11213
12376
|
const common = parseCommonOptions(values, { runtimeDefaults: {
|
|
@@ -11227,7 +12390,8 @@ async function runPolling(opts) {
|
|
|
11227
12390
|
const stateDirs = ensureDaemonStateDirs(sandbox.rootDir);
|
|
11228
12391
|
const slotIdentity = {
|
|
11229
12392
|
agentName: common.agent,
|
|
11230
|
-
runtimeProfileId: profile.id
|
|
12393
|
+
runtimeProfileId: profile.id,
|
|
12394
|
+
runtimeInstanceId
|
|
11231
12395
|
};
|
|
11232
12396
|
const executionPlans = createExecutionPlanCache({
|
|
11233
12397
|
stateDirs,
|
|
@@ -11335,6 +12499,47 @@ async function runPolling(opts) {
|
|
|
11335
12499
|
piAgentDir: piAgentDir.path,
|
|
11336
12500
|
piAgentDirSource: piAgentDir.source
|
|
11337
12501
|
}, "agent-daemon.starting");
|
|
12502
|
+
let reaperRunning = false;
|
|
12503
|
+
const reapRuntimeResources = async () => {
|
|
12504
|
+
if (reaperRunning) return;
|
|
12505
|
+
reaperRunning = true;
|
|
12506
|
+
try {
|
|
12507
|
+
for (const profile of profiles) {
|
|
12508
|
+
const selected = requireRuntime(runtimes, profile.id);
|
|
12509
|
+
const result = await reapRuntimeSlotResources({
|
|
12510
|
+
onIssue: (issue) => {
|
|
12511
|
+
rootLogger.warn({
|
|
12512
|
+
...issue,
|
|
12513
|
+
runtimeProfileId: profile.id
|
|
12514
|
+
}, "agent-daemon.runtime_resource_reap_issue");
|
|
12515
|
+
},
|
|
12516
|
+
runtimeSlotStore: slotRegistry,
|
|
12517
|
+
taskReader: ctx.agent.tasks
|
|
12518
|
+
}, {
|
|
12519
|
+
agentName: selected.common.agent,
|
|
12520
|
+
mainWorktree: resolveMainWorktree$1(selected.sandbox.rootDir),
|
|
12521
|
+
runtimeInstanceId,
|
|
12522
|
+
runtimeProfileId: profile.id,
|
|
12523
|
+
sessionRootDir: selected.stateDirs.piSessionsDir,
|
|
12524
|
+
scratchRootDir: join(selected.stateDirs.rootDir, "task-workspaces"),
|
|
12525
|
+
teamId
|
|
12526
|
+
});
|
|
12527
|
+
if (result.removedSessions > 0 || result.removedWorkspaces > 0 || result.failed > 0 || result.unsafePaths > 0 || result.truncated) rootLogger.info({
|
|
12528
|
+
...result,
|
|
12529
|
+
runtimeProfileId: profile.id
|
|
12530
|
+
}, "agent-daemon.runtime_resources_reaped");
|
|
12531
|
+
}
|
|
12532
|
+
} catch (err) {
|
|
12533
|
+
rootLogger.warn({ err }, "agent-daemon.runtime_resource_reap_failed");
|
|
12534
|
+
} finally {
|
|
12535
|
+
reaperRunning = false;
|
|
12536
|
+
}
|
|
12537
|
+
};
|
|
12538
|
+
await reapRuntimeResources();
|
|
12539
|
+
const reaperTimer = setInterval(() => {
|
|
12540
|
+
reapRuntimeResources();
|
|
12541
|
+
}, 6e4);
|
|
12542
|
+
reaperTimer.unref();
|
|
11338
12543
|
const outputs = [];
|
|
11339
12544
|
try {
|
|
11340
12545
|
runtime = new AgentRuntime({
|
|
@@ -11512,7 +12717,7 @@ async function runPolling(opts) {
|
|
|
11512
12717
|
sessionDir: executionPlan.sessionPersistence.sessionDir,
|
|
11513
12718
|
sessionPath: resolveLatestPiSessionPath(executionPlan.sessionPersistence.sessionDir),
|
|
11514
12719
|
workspaceId: executionPlan.workspaceId,
|
|
11515
|
-
worktreePath: resolveRecordedWorkspacePath$1(stateDirs.rootDir, executionPlan),
|
|
12720
|
+
worktreePath: resolveRecordedWorkspacePath$1(stateDirs.rootDir, sandbox.rootDir, executionPlan),
|
|
11516
12721
|
worktreeBranch: executionPlan.worktreeBranch,
|
|
11517
12722
|
workspaceKind: executionPlan.workspaceKind,
|
|
11518
12723
|
lastTaskId: claimedTask.task.id,
|
|
@@ -11568,15 +12773,23 @@ async function runPolling(opts) {
|
|
|
11568
12773
|
rootLogger.info({ processed: drained.length }, "agent-daemon.drained");
|
|
11569
12774
|
return drained.some((o) => o.status !== "completed") ? 1 : 0;
|
|
11570
12775
|
} finally {
|
|
12776
|
+
clearInterval(reaperTimer);
|
|
11571
12777
|
signalHandlers.dispose();
|
|
11572
12778
|
await slotRegistry.close();
|
|
11573
12779
|
await otelShutdown();
|
|
11574
12780
|
await shutdownLogger();
|
|
11575
12781
|
}
|
|
11576
12782
|
}
|
|
11577
|
-
function resolveRecordedWorkspacePath$1(stateRootDir, executionPlan) {
|
|
12783
|
+
function resolveRecordedWorkspacePath$1(stateRootDir, mountPath, executionPlan) {
|
|
11578
12784
|
if (!executionPlan.workspaceId) return null;
|
|
11579
|
-
return executionPlan.workspaceMode === "scratch_mount" ? join(stateRootDir, "task-workspaces", executionPlan.workspaceId) : join(findMainWorktree(), ".worktrees", executionPlan.workspaceId);
|
|
12785
|
+
return executionPlan.workspaceMode === "scratch_mount" ? join(stateRootDir, "task-workspaces", executionPlan.workspaceId) : join(findMainWorktree(mountPath), ".worktrees", executionPlan.workspaceId);
|
|
12786
|
+
}
|
|
12787
|
+
function resolveMainWorktree$1(mountPath) {
|
|
12788
|
+
try {
|
|
12789
|
+
return findMainWorktree(mountPath);
|
|
12790
|
+
} catch {
|
|
12791
|
+
return null;
|
|
12792
|
+
}
|
|
11580
12793
|
}
|
|
11581
12794
|
function runtimeForClaimedTask(runtimes, claimedTask) {
|
|
11582
12795
|
if (!claimedTask.profileId) throw new Error(`Claimed task ${claimedTask.task.id} did not include a selected runtime profile`);
|
|
@@ -11668,7 +12881,7 @@ async function runOnce(argv) {
|
|
|
11668
12881
|
agent: ctx.agent,
|
|
11669
12882
|
profile: values.profile,
|
|
11670
12883
|
teamId: values.team,
|
|
11671
|
-
cwd:
|
|
12884
|
+
cwd: ctx.agentRootDir
|
|
11672
12885
|
});
|
|
11673
12886
|
validateRuntimeProfilePrerequisites(profile, cfg.profilePrerequisiteEnv, cfg.profilePrerequisitePath);
|
|
11674
12887
|
opts = parseCommonOptions(values, { runtimeDefaults: {
|
|
@@ -11690,9 +12903,11 @@ async function runOnce(argv) {
|
|
|
11690
12903
|
const slotRegistry = createApiRuntimeSlotStore({ agent: ctx.agent });
|
|
11691
12904
|
const runtimeSessionStore = createApiRuntimeSessionStore({ agent: ctx.agent });
|
|
11692
12905
|
const sourceAttemptResolver = createApiSourceAttemptResolver({ agent: ctx.agent });
|
|
12906
|
+
const runtimeInstanceId = createRuntimeInstanceId();
|
|
11693
12907
|
const slotIdentity = {
|
|
11694
12908
|
agentName: opts.agent,
|
|
11695
|
-
runtimeProfileId: profile.id
|
|
12909
|
+
runtimeProfileId: profile.id,
|
|
12910
|
+
runtimeInstanceId
|
|
11696
12911
|
};
|
|
11697
12912
|
const executionPlans = createExecutionPlanCache({
|
|
11698
12913
|
stateDirs,
|
|
@@ -11754,6 +12969,26 @@ async function runOnce(argv) {
|
|
|
11754
12969
|
piAgentDir: piAgentDir.path,
|
|
11755
12970
|
piAgentDirSource: piAgentDir.source
|
|
11756
12971
|
}, "agent-daemon.starting");
|
|
12972
|
+
try {
|
|
12973
|
+
const reaped = await reapRuntimeSlotResources({
|
|
12974
|
+
onIssue: (issue) => {
|
|
12975
|
+
rootLogger.warn(issue, "agent-daemon.runtime_resource_reap_issue");
|
|
12976
|
+
},
|
|
12977
|
+
runtimeSlotStore: slotRegistry,
|
|
12978
|
+
taskReader: ctx.agent.tasks
|
|
12979
|
+
}, {
|
|
12980
|
+
agentName: opts.agent,
|
|
12981
|
+
mainWorktree: resolveMainWorktree(sandbox.rootDir),
|
|
12982
|
+
runtimeInstanceId,
|
|
12983
|
+
runtimeProfileId: profile.id,
|
|
12984
|
+
sessionRootDir: stateDirs.piSessionsDir,
|
|
12985
|
+
scratchRootDir: join(stateDirs.rootDir, "task-workspaces"),
|
|
12986
|
+
teamId: profile.teamId
|
|
12987
|
+
});
|
|
12988
|
+
if (reaped.removedSessions > 0 || reaped.removedWorkspaces > 0 || reaped.failed > 0 || reaped.unsafePaths > 0 || reaped.truncated) rootLogger.info(reaped, "agent-daemon.runtime_resources_reaped");
|
|
12989
|
+
} catch (err) {
|
|
12990
|
+
rootLogger.warn({ err }, "agent-daemon.runtime_resource_reap_failed");
|
|
12991
|
+
}
|
|
11757
12992
|
let runtime = null;
|
|
11758
12993
|
let activeAttemptN = null;
|
|
11759
12994
|
const signalHandlers = installShutdownSignalHandlers({
|
|
@@ -11843,7 +13078,7 @@ async function runOnce(argv) {
|
|
|
11843
13078
|
sessionDir: executionPlan.sessionPersistence.sessionDir,
|
|
11844
13079
|
sessionPath: resolveLatestPiSessionPath(executionPlan.sessionPersistence.sessionDir),
|
|
11845
13080
|
workspaceId: executionPlan.workspaceId,
|
|
11846
|
-
worktreePath: resolveRecordedWorkspacePath(stateDirs.rootDir, executionPlan),
|
|
13081
|
+
worktreePath: resolveRecordedWorkspacePath(stateDirs.rootDir, sandbox.rootDir, executionPlan),
|
|
11847
13082
|
worktreeBranch: executionPlan.worktreeBranch,
|
|
11848
13083
|
workspaceKind: executionPlan.workspaceKind,
|
|
11849
13084
|
lastTaskId: claimedTask.task.id,
|
|
@@ -11939,9 +13174,16 @@ async function runOnce(argv) {
|
|
|
11939
13174
|
await shutdownLogger();
|
|
11940
13175
|
}
|
|
11941
13176
|
}
|
|
11942
|
-
function resolveRecordedWorkspacePath(stateRootDir, executionPlan) {
|
|
13177
|
+
function resolveRecordedWorkspacePath(stateRootDir, mountPath, executionPlan) {
|
|
11943
13178
|
if (!executionPlan.workspaceId) return null;
|
|
11944
|
-
return executionPlan.workspaceMode === "scratch_mount" ? join(stateRootDir, "task-workspaces", executionPlan.workspaceId) : join(findMainWorktree(), ".worktrees", executionPlan.workspaceId);
|
|
13179
|
+
return executionPlan.workspaceMode === "scratch_mount" ? join(stateRootDir, "task-workspaces", executionPlan.workspaceId) : join(findMainWorktree(mountPath), ".worktrees", executionPlan.workspaceId);
|
|
13180
|
+
}
|
|
13181
|
+
function resolveMainWorktree(mountPath) {
|
|
13182
|
+
try {
|
|
13183
|
+
return findMainWorktree(mountPath);
|
|
13184
|
+
} catch {
|
|
13185
|
+
return null;
|
|
13186
|
+
}
|
|
11945
13187
|
}
|
|
11946
13188
|
//#endregion
|
|
11947
13189
|
//#region src/cli/poll.ts
|