@corca-org/ceal-host-linux-arm64 1.0.8 → 1.0.10
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 +2 -2
- package/bin/ceal-host +0 -0
- package/libexec/ceal-host/claude-hook.mjs +149 -46
- package/libexec/ceal-host/claude-invocation-authentication.mjs +103 -127
- package/libexec/ceal-host/claude-producer.mjs +76 -24
- package/libexec/ceal-host/codex-hook.mjs +148 -47
- package/libexec/ceal-host/codex-invocation-authentication.mjs +136 -131
- package/libexec/ceal-host/codex-producer.mjs +136 -32
- package/libexec/ceal-host/control.mjs +157 -40
- package/libexec/ceal-host/relay.mjs +240 -58
- package/package.json +1 -1
- package/share/ceal-host/bundle-manifest.json +12 -12
- package/share/ceal-host/bundle-manifest.sigstore.json +1 -1
|
@@ -78,11 +78,28 @@ var client_wire_contract_default = {
|
|
|
78
78
|
],
|
|
79
79
|
bare_document_fields: [
|
|
80
80
|
"invocation",
|
|
81
|
-
"
|
|
81
|
+
"required_action_sequence",
|
|
82
|
+
"entrypoints",
|
|
82
83
|
"common_concepts",
|
|
83
84
|
"operations",
|
|
84
85
|
"catalog_revision"
|
|
85
86
|
],
|
|
87
|
+
prompt_field: "prompt",
|
|
88
|
+
prompt_schema_version: "ceal.prompt.v1",
|
|
89
|
+
focused_prompt_document_fields: [
|
|
90
|
+
"catalog_revision",
|
|
91
|
+
"prompt"
|
|
92
|
+
],
|
|
93
|
+
focused_prompt_continuation_document_fields: [
|
|
94
|
+
"catalog_revision",
|
|
95
|
+
"remaining_work",
|
|
96
|
+
"prompt"
|
|
97
|
+
],
|
|
98
|
+
discovery_command: "discovery",
|
|
99
|
+
discovery_manifest_schema_version: "ceal.discovery_manifest.v1",
|
|
100
|
+
discovery_manifest_document_fields: [
|
|
101
|
+
"discovery_manifest"
|
|
102
|
+
],
|
|
86
103
|
exit_code_max: 125,
|
|
87
104
|
bare_document_max_bytes: 65536,
|
|
88
105
|
complete_max_bytes: 66019,
|
|
@@ -109,8 +126,15 @@ var CEAL_VERIFIED_ARTIFACT_MAX_BYTES = artifact.max_bytes;
|
|
|
109
126
|
var CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_MAX_BYTES = artifact.envelope_max_bytes;
|
|
110
127
|
var CEAL_COMMAND_REQUEST_SCHEMA_VERSION = request.schema_version;
|
|
111
128
|
var CEAL_COMMAND_REQUEST_MAX_BYTES = request.absolute_transport_max_bytes;
|
|
112
|
-
var CEAL_COMMAND_RESPONSE_BARE_DOCUMENT_FIELDS = response.bare_document_fields;
|
|
113
129
|
var CEAL_COMMAND_RESPONSE_BARE_DOCUMENT_MAX_BYTES = response.bare_document_max_bytes;
|
|
130
|
+
var CEAL_COMMAND_RESPONSE_PROMPT_FIELD = response.prompt_field;
|
|
131
|
+
var CEAL_COMMAND_RESPONSE_PROMPT_SCHEMA_VERSION = response.prompt_schema_version;
|
|
132
|
+
var CEAL_COMMAND_RESPONSE_PROMPT_DOCUMENT_FIELDS = Object.freeze([...response.bare_document_fields, response.prompt_field]);
|
|
133
|
+
var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_DOCUMENT_FIELDS = Object.freeze([...response.focused_prompt_document_fields]);
|
|
134
|
+
var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_CONTINUATION_DOCUMENT_FIELDS = Object.freeze([...response.focused_prompt_continuation_document_fields]);
|
|
135
|
+
var CEAL_COMMAND_RESPONSE_DISCOVERY_COMMAND = response.discovery_command;
|
|
136
|
+
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_SCHEMA_VERSION = response.discovery_manifest_schema_version;
|
|
137
|
+
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_DOCUMENT_FIELDS = Object.freeze([...response.discovery_manifest_document_fields]);
|
|
114
138
|
var CEAL_COMMAND_RESPONSE_MAX_BYTES = response.absolute_transport_max_bytes;
|
|
115
139
|
|
|
116
140
|
// packages/ceal-client-protocol/src/vocabulary.ts
|
|
@@ -146,7 +170,7 @@ var CEAL_OPERATION_RECOVERY_KINDS = vocabulary(["none", "reconcile", "compensate
|
|
|
146
170
|
var CEAL_OPERATION_RECOVERY_STATUSES = vocabulary(["not_started", "active", "completed"]);
|
|
147
171
|
var CEAL_OPERATION_PROVIDER_READBACK_AVAILABILITY = vocabulary(["not_started", "not_applicable", "not_available", "pending", "available"]);
|
|
148
172
|
var CEAL_OPERATION_OFFERED_HANDOFF_STATES = vocabulary(["accepted", "rejected", "unknown"]);
|
|
149
|
-
var CEAL_OPERATION_RECEIPT_AUTHORITY_KEYS = Object.freeze(["instance_ref", "
|
|
173
|
+
var CEAL_OPERATION_RECEIPT_AUTHORITY_KEYS = Object.freeze(["instance_ref", "access_group_ref", "principal_ref", "execution_subject_ref", "authority_revision_ref"]);
|
|
150
174
|
var CEAL_OPERATION_APPROVAL_DISPOSITIONS = vocabulary([
|
|
151
175
|
"approval_not_required_by_policy",
|
|
152
176
|
"interactive_pending",
|
|
@@ -161,6 +185,8 @@ var CEAL_CAPABILITY_READINESS_VALUES = vocabulary(["ready", "degraded", "unavail
|
|
|
161
185
|
var CEAL_TARGET_REQUIREMENTS = vocabulary(["required", "optional", "none"]);
|
|
162
186
|
var CEAL_AUDIT_OUTCOMES = vocabulary(["succeeded", "denied", "failed"]);
|
|
163
187
|
var CEAL_GATEWAY_PROVIDER_STEP_OUTCOMES = vocabulary(["completed", "rejected", "throttled", "failed"]);
|
|
188
|
+
var CEAL_GATEWAY_READ_REUSE_DISPOSITIONS = vocabulary(["response_cache_hit", "corpus_hit", "corpus_hit_after_revalidation", "corpus_partial_provider_supplement", "provider_direct", "provider_continuation", "reuse_unavailable"]);
|
|
189
|
+
var CEAL_GATEWAY_READ_REUSE_UNAVAILABLE_REASONS = vocabulary(["not_reported", "storage_unavailable", "coverage_incomplete", "freshness_refresh_required", "not_reusable", "bypassed"]);
|
|
164
190
|
var CEAL_POLICY_DECISIONS = vocabulary(["allowed", "denied", "not_evaluated"]);
|
|
165
191
|
var CEAL_CONNECTOR_ROUTE_PHASES = vocabulary(["scope_observation", "target_selection", "route_resolution"]);
|
|
166
192
|
var CEAL_CONNECTOR_ROUTE_CAUSES = vocabulary(["provider_throttled", "provider_unavailable", "binding_invalid", "scope_limit_exceeded"]);
|
|
@@ -433,8 +459,10 @@ function requireIsoTimestamp(value, message) {
|
|
|
433
459
|
var JSON_DESCRIPTION_CONTROL_CHARACTER = new RegExp("\\p{Cc}", "u");
|
|
434
460
|
|
|
435
461
|
// packages/ceal-client-protocol/src/operation-contract-validation.ts
|
|
436
|
-
var CEAL_OPERATION_AUTHORITY_POLICY_KEYS = Object.freeze(["
|
|
462
|
+
var CEAL_OPERATION_AUTHORITY_POLICY_KEYS = Object.freeze(["access_group", "instance_binding", "target", "admission_recheck"]);
|
|
437
463
|
var MAX_OPERATION_INPUT_RESOLVER_BINDINGS = 96;
|
|
464
|
+
var CEAL_OPERATION_DESCRIPTOR_REQUIRED_ENVELOPE_KEYS = Object.freeze(["schema_version", "id", "input_contract", "result_contract", "policy"]);
|
|
465
|
+
var CEAL_OPERATION_DESCRIPTOR_OPTIONAL_ENVELOPE_KEYS = Object.freeze(["input_resolution", "summary"]);
|
|
438
466
|
var CEAL_OPERATION_RESULT_KEYS = vocabulary(["ok", "operation_id", "operation_receipt", "schema_version", "value"]);
|
|
439
467
|
var CEAL_OPERATION_COMPACT_RESULT_KEYS = vocabulary(["ok", "operation_evidence", "operation_id", "schema_version", "value"]);
|
|
440
468
|
|
|
@@ -508,6 +536,7 @@ var CEAL_SCHEMA_LITERALS = [
|
|
|
508
536
|
"ceal.operation_descriptor.v1",
|
|
509
537
|
"ceal.operation_error.v1",
|
|
510
538
|
"ceal.operation_failure.v1",
|
|
539
|
+
"ceal.operation_failure.compact.v1",
|
|
511
540
|
"ceal.operation_receipt.v1",
|
|
512
541
|
"ceal.operation_result.v1",
|
|
513
542
|
"ceal.operation_result.compact.v1",
|
|
@@ -533,17 +562,16 @@ var CEAL_BOUNDED_SERIES_CATALOG = Object.freeze({
|
|
|
533
562
|
engagement_signal: (root) => join(root, "runtime-state", "slack-feedback.jsonl"),
|
|
534
563
|
runtime_error: (root) => join(root, "runtime-state", "runtime-errors.jsonl"),
|
|
535
564
|
turn_bridge_request: (root) => join(root, ".ceal", "turn-bridge", "requests.jsonl"),
|
|
536
|
-
channel_log: (root) => join(root, "log.jsonl"),
|
|
537
565
|
thread_run_events: (root) => join(root, "run-events.jsonl"),
|
|
538
566
|
bounded_store_sidecar: (root) => `${root}.jsonl`,
|
|
539
567
|
gateway_audit_archive: (root) => `${root}.jsonl`,
|
|
540
568
|
gateway_capability_audit: (root) => join(root, "capability-audit.jsonl"),
|
|
541
569
|
gateway_retrieval_waste_partition: (root) => `${root}.jsonl`,
|
|
542
570
|
gateway_access_policy_publication: (root) => join(root, "access-policy-publications.jsonl"),
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
571
|
+
gateway_access_group_connector_control_audit: (root) => `${root}.audit.jsonl`,
|
|
572
|
+
gateway_access_group_connector_scope_audit: (root) => join(root, "profile-connector-scope-audit.jsonl"),
|
|
573
|
+
gateway_access_group_connector_activity_scope_audit: (root) => join(root, "profile-connector-activity-scope-audit.jsonl"),
|
|
574
|
+
gateway_access_group_connector_readiness_audit: (root) => join(root, "profile-connector-readiness.audit.jsonl"),
|
|
547
575
|
gateway_organization_audit_ledger: (root) => join(root, "organization-ledger.jsonl"),
|
|
548
576
|
gateway_personal_client_audit: (root) => join(root, "audit.jsonl"),
|
|
549
577
|
gateway_personal_client_access_audit: (root) => join(root, "access-audit.jsonl"),
|
|
@@ -594,12 +622,6 @@ var CEAL_AGENT_SESSION_COMMIT_KEYS = vocabulary(["attempt_ref", "expected_sessio
|
|
|
594
622
|
// packages/ceal-client-protocol/src/operation-next-actions.ts
|
|
595
623
|
var CALLER_RECOVERABLE_NEXT_ACTION_VALUES = [
|
|
596
624
|
"select_did_you_mean",
|
|
597
|
-
// The graph, not the argument list, is what the caller must change: the
|
|
598
|
-
// resolver that owns this input has no producing node upstream, and no edit
|
|
599
|
-
// to the invocation can conjure one. `resolver_dependency_absent` carried no
|
|
600
|
-
// remedy at all rather than borrow a word that means something else, so the
|
|
601
|
-
// scorer read a fully-diagnosed, caller-fixable refusal as a failed run.
|
|
602
|
-
"request.graph.append",
|
|
603
625
|
"choose_new_output_path",
|
|
604
626
|
"choose_new_idempotency_key",
|
|
605
627
|
"restart_search",
|
|
@@ -651,8 +673,6 @@ var NON_REMEDY_NEXT_ACTION_VALUES = [
|
|
|
651
673
|
"reconcile_occurrence",
|
|
652
674
|
"reduce_request_size",
|
|
653
675
|
"repair_or_adopt_session",
|
|
654
|
-
"request.effect_approval.read",
|
|
655
|
-
"request.run",
|
|
656
676
|
"retry",
|
|
657
677
|
// The owner -- a correlation hook, an approval hook -- is not serving right
|
|
658
678
|
// now. The caller changes nothing and the same call succeeds once the owner
|
|
@@ -749,12 +769,12 @@ var CEAL_REQUEST_JSON_SCHEMA = {
|
|
|
749
769
|
additionalProperties: false,
|
|
750
770
|
properties: {
|
|
751
771
|
instance_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
752
|
-
|
|
772
|
+
access_group_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
753
773
|
principal_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
754
774
|
execution_subject_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
755
775
|
authority_revision_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source }
|
|
756
776
|
},
|
|
757
|
-
required: ["instance_ref", "
|
|
777
|
+
required: ["instance_ref", "access_group_ref", "principal_ref", "execution_subject_ref", "authority_revision_ref"]
|
|
758
778
|
},
|
|
759
779
|
prompt_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
760
780
|
host_session_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
@@ -886,7 +906,7 @@ var CEAL_HOST_OBSERVATION_KINDS = vocabulary(["prompt", "session", "turn", "mode
|
|
|
886
906
|
function isCealHostPromptObservationValue(value) {
|
|
887
907
|
return isOperationRecord(value) && Object.keys(value).length === 1 && isCealDigest(value.body_sha256);
|
|
888
908
|
}
|
|
889
|
-
var HOST_RESERVED_KEY = /^(?:admission|approval|audit|authorization|cancellation|capability|effect|grant|occurrence|operation|policy|profile|provider_readback|receipt|reconciliation|replay|target|write_request)(?:_|$)/iu;
|
|
909
|
+
var HOST_RESERVED_KEY = /^(?:access_group|admission|approval|audit|authorization|cancellation|capability|effect|grant|occurrence|operation|policy|profile|provider_readback|receipt|reconciliation|replay|target|write_request)(?:_|$)/iu;
|
|
890
910
|
function assertHostObservationValue(value, kind) {
|
|
891
911
|
if (value === void 0) invalid("Ceal Host observation value is invalid.");
|
|
892
912
|
if (kind === "prompt" && !isCealHostPromptObservationValue(value)) invalid("Ceal Host prompt observation must contain only its body digest.");
|
|
@@ -906,6 +926,14 @@ function inspectHostKeys(value) {
|
|
|
906
926
|
}
|
|
907
927
|
}
|
|
908
928
|
|
|
929
|
+
// packages/ceal-client-protocol/src/host-prompt-ref.ts
|
|
930
|
+
var CEAL_HOST_PROMPT_DIGEST_PATTERN = "^[a-f0-9]{64}$";
|
|
931
|
+
var PROMPT_DIGEST = new RegExp(CEAL_HOST_PROMPT_DIGEST_PATTERN, "u");
|
|
932
|
+
function hostProducerPromptRef(promptSha256) {
|
|
933
|
+
if (!PROMPT_DIGEST.test(promptSha256)) throw new TypeError("Canonical Host prompt digest is invalid.");
|
|
934
|
+
return `ceal-host-prompt:${promptSha256}`;
|
|
935
|
+
}
|
|
936
|
+
|
|
909
937
|
// packages/ceal-client-protocol/src/request-effect-approval.ts
|
|
910
938
|
var CEAL_EFFECT_APPROVAL_DECISION_CHECK_PHRASES = Object.freeze([
|
|
911
939
|
"observed after this approval was raised and before it expires",
|
|
@@ -921,6 +949,12 @@ var OWNER_WRITE_STATES = Object.freeze(["attempt_started", "provider_acknowledge
|
|
|
921
949
|
var OWNER_EFFECT_STATES = Object.freeze(["none", "applied", "failed", "unknown", "reconciled"]);
|
|
922
950
|
var OWNER_RECEIPT_STATES = Object.freeze(["pending", "available", "failed", "unknown", "reconciled"]);
|
|
923
951
|
|
|
952
|
+
// packages/ceal-client-protocol/src/thread-excerpt.ts
|
|
953
|
+
var CEAL_THREAD_RECENT_WINDOW = 6;
|
|
954
|
+
var CEAL_THREAD_LAST_APP_MESSAGES_WINDOW = 3;
|
|
955
|
+
var CEAL_THREAD_OLDER_SUMMARY_WINDOW = 4;
|
|
956
|
+
var CEAL_FED_THREAD_MESSAGE_LIMIT = CEAL_THREAD_RECENT_WINDOW + CEAL_THREAD_OLDER_SUMMARY_WINDOW + CEAL_THREAD_LAST_APP_MESSAGES_WINDOW;
|
|
957
|
+
|
|
924
958
|
// packages/ceal-client-protocol/src/request-graph-readiness.ts
|
|
925
959
|
var REQUEST_GRAPH_PRODUCER_TO_APPEND_SCHEMA = {
|
|
926
960
|
type: "object",
|
|
@@ -1000,6 +1034,13 @@ var CEAL_REQUEST_GRAPH_NODE_PREPARE_READINESS_JSON_SCHEMA = {
|
|
|
1000
1034
|
var REQUIRED_FIELDS = Object.freeze(["schema_version", "operation_id", "local_path", "content_json_pointer", "size_bytes", "sha256", "read_argv"]);
|
|
1001
1035
|
var FIELDS = /* @__PURE__ */ new Set([...REQUIRED_FIELDS, "local_result_root", "model_disclosure"]);
|
|
1002
1036
|
|
|
1037
|
+
// packages/ceal-client-protocol/src/session-start-affordance.ts
|
|
1038
|
+
var CEAL_SESSION_ENTRY_INVOCATION = "ceal";
|
|
1039
|
+
var CEAL_LINK_RESOURCE_PRECEDENCE = `When the user asks to use Ceal or provides a link to information that may be available through installed organizational capabilities, run bare \`${CEAL_SESSION_ENTRY_INVOCATION}\`. The Host supplies the current user prompt without exposing it to the client command, and the Gateway returns the applicable entry in that one response. Treat a supplied link as a candidate Ceal resource rather than a public web-search target. Reach for a generic web fetch or web search only when the Gateway offered nothing.`;
|
|
1040
|
+
|
|
1041
|
+
// packages/ceal-client-protocol/src/discovery-manifest.ts
|
|
1042
|
+
var CEAL_DISCOVERY_MANIFEST_CONNECTOR_KINDS = vocabulary(["github", "google-workspace", "notion", "slack"]);
|
|
1043
|
+
|
|
1003
1044
|
// packages/ceal-client-protocol/src/conversation-contracts.ts
|
|
1004
1045
|
var CEAL_APPROVAL_POLICY_KINDS = vocabulary(["requester_only", "named_users", "role_based"]);
|
|
1005
1046
|
var CEAL_APPROVAL_TARGET_KINDS = vocabulary([
|
|
@@ -1216,7 +1257,7 @@ var CEAL_PRESENTATION_INTENTS = vocabulary(["progress", ...CEAL_FINAL_PRESENTATI
|
|
|
1216
1257
|
|
|
1217
1258
|
// packages/ceal-client-protocol/src/personal-client-vocabulary.ts
|
|
1218
1259
|
var CEAL_PERSONAL_CLIENT_BINDING_KEYS = vocabulary([
|
|
1219
|
-
"
|
|
1260
|
+
"access_group_ref",
|
|
1220
1261
|
"membership_ref",
|
|
1221
1262
|
"registration_ref",
|
|
1222
1263
|
"client_ref",
|
|
@@ -1231,7 +1272,8 @@ var CEAL_REFRESH_FAILURE_CODES = vocabulary([
|
|
|
1231
1272
|
"refresh_replayed",
|
|
1232
1273
|
"refresh_revoked",
|
|
1233
1274
|
"authority_replaced",
|
|
1234
|
-
"refresh_recovery_unavailable"
|
|
1275
|
+
"refresh_recovery_unavailable",
|
|
1276
|
+
"refresh_recovery_expired"
|
|
1235
1277
|
]);
|
|
1236
1278
|
|
|
1237
1279
|
// packages/ceal-client-protocol/src/device-enrollment.ts
|
|
@@ -1446,7 +1488,6 @@ var HOST_PRODUCER_FRAME_SCHEMA = "ceal.host_producer_frame.v1";
|
|
|
1446
1488
|
var HOST_PRODUCER_MAX_JSON_BYTES = 262144;
|
|
1447
1489
|
var HOST_PRODUCER_FRAME_LENGTH_BYTES = Uint32Array.BYTES_PER_ELEMENT;
|
|
1448
1490
|
var SAFE_REF3 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
1449
|
-
var DIGEST2 = /^[a-f0-9]{64}$/u;
|
|
1450
1491
|
var PRODUCERS = /* @__PURE__ */ new Set(["codex", "claude"]);
|
|
1451
1492
|
var HOST_PRODUCER_FRAME_KINDS = ["session_started", "turn_started", "user_input", "turn_terminal", "producer_status"];
|
|
1452
1493
|
var FRAME_KINDS = new Set(HOST_PRODUCER_FRAME_KINDS);
|
|
@@ -1487,10 +1528,6 @@ function decodeHostProducerFrame(input) {
|
|
|
1487
1528
|
validateFrame(value);
|
|
1488
1529
|
return value;
|
|
1489
1530
|
}
|
|
1490
|
-
function hostProducerPromptRef(promptSha256) {
|
|
1491
|
-
if (!DIGEST2.test(promptSha256)) throw new TypeError("Canonical Host prompt digest is invalid.");
|
|
1492
|
-
return `ceal-host-prompt:${promptSha256}`;
|
|
1493
|
-
}
|
|
1494
1531
|
function validateFrame(value) {
|
|
1495
1532
|
if (!record(value)) throw new HostProducerFrameError("invalid_frame_shape");
|
|
1496
1533
|
if (value.schema_version !== HOST_PRODUCER_FRAME_SCHEMA) throw new HostProducerFrameError("unsupported_frame_schema", `unsupported_frame_schema: ${refusalFact("schema_version", value.schema_version, HOST_PRODUCER_FRAME_SCHEMA)}`);
|
|
@@ -1600,12 +1637,19 @@ var RELAY_QUARANTINE_MAX_BYTES = 16 * 1024 * 1024;
|
|
|
1600
1637
|
|
|
1601
1638
|
// host/relay/src/relay-admission-store.ts
|
|
1602
1639
|
var DEFAULT_LIMITS = { global_count: 8192, global_bytes: 64 * 1024 * 1024, producer_count: 4096, producer_bytes: 32 * 1024 * 1024 };
|
|
1640
|
+
var RETRY_SECONDS = [1, 2, 4, 8, 16, 32, 60];
|
|
1641
|
+
var MAX_RETRYABLE_ATTEMPTS = RETRY_SECONDS.length + 10;
|
|
1603
1642
|
|
|
1604
1643
|
// host/relay/src/relay-request-binding-store.ts
|
|
1605
1644
|
var MAX_STATE_BYTES = 8 * 1024 * 1024;
|
|
1606
1645
|
|
|
1607
1646
|
// host/relay/src/relay-ipc.ts
|
|
1608
1647
|
import { createConnection, createServer } from "node:net";
|
|
1648
|
+
|
|
1649
|
+
// host/relay/src/current-prompt-custody.ts
|
|
1650
|
+
var HOST_CURRENT_PROMPT_MAX_BYTES = 256 * 1024;
|
|
1651
|
+
|
|
1652
|
+
// host/relay/src/relay-ipc.ts
|
|
1609
1653
|
var HOST_RELAY_REQUEST_BINDING_KEYS = Object.freeze([
|
|
1610
1654
|
"schema_version",
|
|
1611
1655
|
"producer_id",
|
|
@@ -1622,6 +1666,8 @@ var HOST_RELAY_REQUEST_BINDING_KEYS = Object.freeze([
|
|
|
1622
1666
|
"host_input_ref"
|
|
1623
1667
|
]);
|
|
1624
1668
|
var HOST_RELAY_IPC_RESPONSE_SCHEMA = "ceal.host_relay_admission.v1";
|
|
1669
|
+
var HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA = "ceal.host_relay_current_prompt_register.v1";
|
|
1670
|
+
var HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA = "ceal.host_relay_current_prompt_result.v1";
|
|
1625
1671
|
var HOST_RELAY_IPC_LENGTH_BYTES = Uint32Array.BYTES_PER_ELEMENT;
|
|
1626
1672
|
var HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES = 4096;
|
|
1627
1673
|
var HostRelayIpcError = class extends Error {
|
|
@@ -1644,22 +1690,42 @@ var HostRelayIpcAdmissionPort = class {
|
|
|
1644
1690
|
return { code: response2.code, admitted_through_sequence: response2.admitted_through_sequence, delivered_through_sequence: response2.delivered_through_sequence };
|
|
1645
1691
|
}
|
|
1646
1692
|
};
|
|
1693
|
+
var HostRelayCurrentPromptPort = class {
|
|
1694
|
+
endpoint;
|
|
1695
|
+
timeout_ms;
|
|
1696
|
+
constructor(endpoint, timeoutMs = 5e3) {
|
|
1697
|
+
this.endpoint = endpoint;
|
|
1698
|
+
this.timeout_ms = timeoutMs;
|
|
1699
|
+
}
|
|
1700
|
+
async register(input) {
|
|
1701
|
+
const request2 = { schema_version: HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA, ...input };
|
|
1702
|
+
const response2 = await exchange(this.endpoint, encodeLengthPrefixed(request2), this.timeout_ms, decodeCurrentPromptResponseBuffer);
|
|
1703
|
+
if (response2.status !== "registered") throw new HostRelayIpcError("relay_unavailable", response2.status);
|
|
1704
|
+
}
|
|
1705
|
+
};
|
|
1647
1706
|
function submitHostProducerFrame(endpoint, frame, timeoutMs = 5e3) {
|
|
1648
1707
|
return exchange(endpoint, encodeHostProducerFrame(frame), timeoutMs, decodeResponseBuffer);
|
|
1649
1708
|
}
|
|
1650
|
-
function exchange(endpoint, encoded, timeoutMs, decode) {
|
|
1709
|
+
function exchange(endpoint, encoded, timeoutMs, decode, signal) {
|
|
1651
1710
|
return new Promise((resolve, reject2) => {
|
|
1652
1711
|
const socket = createConnection(endpoint);
|
|
1653
1712
|
let buffer = Buffer.alloc(0);
|
|
1654
1713
|
let settled = false;
|
|
1714
|
+
const aborted = () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC was cancelled."));
|
|
1655
1715
|
const finish = (error, response2) => {
|
|
1656
1716
|
if (settled) return;
|
|
1657
1717
|
settled = true;
|
|
1718
|
+
signal?.removeEventListener("abort", aborted);
|
|
1658
1719
|
socket.destroy();
|
|
1659
1720
|
if (error !== null) reject2(error);
|
|
1660
1721
|
else if (response2 !== void 0) resolve(response2);
|
|
1661
1722
|
};
|
|
1662
|
-
socket.setTimeout(timeoutMs, () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC timed out.")));
|
|
1723
|
+
if (timeoutMs !== void 0) socket.setTimeout(timeoutMs, () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC timed out.")));
|
|
1724
|
+
if (signal?.aborted === true) {
|
|
1725
|
+
aborted();
|
|
1726
|
+
return;
|
|
1727
|
+
}
|
|
1728
|
+
signal?.addEventListener("abort", aborted, { once: true });
|
|
1663
1729
|
socket.once("error", () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC is unavailable.")));
|
|
1664
1730
|
socket.once("connect", () => socket.write(encoded));
|
|
1665
1731
|
socket.on("data", (chunk) => {
|
|
@@ -1712,6 +1778,34 @@ function decodeResponseBuffer(buffer) {
|
|
|
1712
1778
|
if (buffer.length !== length + HOST_RELAY_IPC_LENGTH_BYTES) throw new HostRelayIpcError("relay_unavailable", `Host Relay IPC returned trailing bytes: ${refusalFacts([{ name: "declared_bytes", value: length, expected: `the received message length minus ${HOST_RELAY_IPC_LENGTH_BYTES}` }, { name: "received_bytes", value: buffer.byteLength, expected: `exactly ${length + HOST_RELAY_IPC_LENGTH_BYTES}` }])}.`);
|
|
1713
1779
|
return decodeHostRelayIpcResponse(buffer);
|
|
1714
1780
|
}
|
|
1781
|
+
function decodeCurrentPromptResponseBuffer(buffer) {
|
|
1782
|
+
const value = decodeLengthPrefixedJson(buffer, HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES);
|
|
1783
|
+
if (value === null) return null;
|
|
1784
|
+
if (!record2(value) || !exactKeys2(value, ["schema_version", "status"]) || value.schema_version !== HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA || value.status !== "registered" && value.status !== "current_prompt_unavailable") throw new HostRelayIpcError("relay_unavailable");
|
|
1785
|
+
return { schema_version: HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA, status: value.status };
|
|
1786
|
+
}
|
|
1787
|
+
function decodeLengthPrefixedJson(input, maximum) {
|
|
1788
|
+
if (input.length < HOST_RELAY_IPC_LENGTH_BYTES) return null;
|
|
1789
|
+
const length = input.readUInt32BE(0);
|
|
1790
|
+
if (length === 0 || length > maximum) throw new HostRelayIpcError("relay_unavailable", `Host Relay IPC message length is invalid: ${refusalFact("declared_bytes", length, `between 1 and ${maximum}`)}.`);
|
|
1791
|
+
if (input.length < length + HOST_RELAY_IPC_LENGTH_BYTES) return null;
|
|
1792
|
+
if (input.length !== length + HOST_RELAY_IPC_LENGTH_BYTES) throw new HostRelayIpcError("relay_unavailable", `Host Relay IPC message has trailing bytes: ${refusalFacts([{ name: "declared_bytes", value: length, expected: `the received message length minus ${HOST_RELAY_IPC_LENGTH_BYTES}` }, { name: "received_bytes", value: input.byteLength, expected: `exactly ${length + HOST_RELAY_IPC_LENGTH_BYTES}` }])}.`);
|
|
1793
|
+
try {
|
|
1794
|
+
return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(input.subarray(HOST_RELAY_IPC_LENGTH_BYTES)));
|
|
1795
|
+
} catch {
|
|
1796
|
+
throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC message is invalid.");
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
function encodeLengthPrefixed(value) {
|
|
1800
|
+
const body = Buffer.from(JSON.stringify(value), "utf8");
|
|
1801
|
+
const output = Buffer.allocUnsafe(body.length + HOST_RELAY_IPC_LENGTH_BYTES);
|
|
1802
|
+
output.writeUInt32BE(body.length, 0);
|
|
1803
|
+
body.copy(output, HOST_RELAY_IPC_LENGTH_BYTES);
|
|
1804
|
+
return output;
|
|
1805
|
+
}
|
|
1806
|
+
function exactKeys2(value, keys) {
|
|
1807
|
+
return Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
|
|
1808
|
+
}
|
|
1715
1809
|
|
|
1716
1810
|
// host/codex/src/codex-producer.ts
|
|
1717
1811
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -1730,7 +1824,7 @@ function invocationContextKey(identity) {
|
|
|
1730
1824
|
return cealRequestSha256({ host_source_ref: identity.host_source_ref, host_session_ref: identity.host_session_ref });
|
|
1731
1825
|
}
|
|
1732
1826
|
function hasHostInvocationIdentityKeys(value) {
|
|
1733
|
-
return
|
|
1827
|
+
return exactKeys3(value, HOST_INVOCATION_IDENTITY_KEYS);
|
|
1734
1828
|
}
|
|
1735
1829
|
function hasHostInvocationContextKeys(value, optional = []) {
|
|
1736
1830
|
return requiredKeys(value, HOST_INVOCATION_CONTEXT_REQUIRED_KEYS, optional);
|
|
@@ -1746,7 +1840,7 @@ function invocationContextFromTurn(identity, promptRef, expiresAt, descriptor) {
|
|
|
1746
1840
|
descriptor.validate(context);
|
|
1747
1841
|
return Object.freeze(context);
|
|
1748
1842
|
}
|
|
1749
|
-
function
|
|
1843
|
+
function exactKeys3(value, keys) {
|
|
1750
1844
|
const actual = Object.keys(value);
|
|
1751
1845
|
return actual.length === keys.length && keys.every((key) => Object.hasOwn(value, key)) && actual.every((key) => keys.includes(key));
|
|
1752
1846
|
}
|
|
@@ -3090,6 +3184,8 @@ var CodexTranscriptWatcher = class {
|
|
|
3090
3184
|
now;
|
|
3091
3185
|
log;
|
|
3092
3186
|
retriedMalformedQuarantines = /* @__PURE__ */ new Set();
|
|
3187
|
+
producerInstallationRef;
|
|
3188
|
+
registerCurrentPrompt;
|
|
3093
3189
|
constructor(options) {
|
|
3094
3190
|
if (typeof options.outbox_dir !== "string" || options.outbox_dir.length === 0) throw new CodexHostAdapterError("configuration", "Codex transcript watcher outbox is invalid.");
|
|
3095
3191
|
this.store = new CodexOutboxStore(options.outbox_dir);
|
|
@@ -3099,6 +3195,8 @@ var CodexTranscriptWatcher = class {
|
|
|
3099
3195
|
process.stderr.write(`${line}
|
|
3100
3196
|
`);
|
|
3101
3197
|
});
|
|
3198
|
+
this.producerInstallationRef = options.producer_installation_ref;
|
|
3199
|
+
this.registerCurrentPrompt = options.register_current_prompt;
|
|
3102
3200
|
}
|
|
3103
3201
|
async scanOnce() {
|
|
3104
3202
|
const registrations = await this.store.listTranscriptRegistrations();
|
|
@@ -3243,10 +3341,15 @@ var CodexTranscriptWatcher = class {
|
|
|
3243
3341
|
created_at: record3.timestamp,
|
|
3244
3342
|
expires_at: expiration(this.now, this.outboxRetentionMs)
|
|
3245
3343
|
};
|
|
3344
|
+
await this.registerPrompt(origin, registration, activeTask, currentPromptRef, record3.prompt, envelope.expires_at);
|
|
3246
3345
|
await this.store.put(envelope);
|
|
3247
3346
|
if (origin) await this.store.activateInvocationContext(identity, promptRef, envelope.expires_at);
|
|
3248
3347
|
return { activeTask: { ...activeTask, origin_host_input_ref: activeTask.origin_host_input_ref ?? hostInputRef, prompt_ref: activeTask.prompt_ref ?? currentPromptRef }, enqueued: 1 };
|
|
3249
3348
|
}
|
|
3349
|
+
async registerPrompt(origin, registration, activeTask, promptRef, prompt, expiresAt) {
|
|
3350
|
+
if (!origin || this.producerInstallationRef === void 0 || this.registerCurrentPrompt === void 0) return;
|
|
3351
|
+
await this.registerCurrentPrompt({ producer_id: "codex", producer_installation_ref: this.producerInstallationRef, local_session_ref: registration.host_session_ref, local_turn_ref: activeTask.host_turn_ref, prompt_ref: promptRef, current_prompt: prompt, context_expires_at: expiresAt });
|
|
3352
|
+
}
|
|
3250
3353
|
async processTerminal(registration, activeTask, record3) {
|
|
3251
3354
|
if (activeTask === void 0 || activeTask.codex_turn_id !== record3.turn_id || activeTask.origin_host_input_ref === void 0 || activeTask.prompt_ref === void 0) return { ...activeTask === void 0 ? {} : { activeTask }, enqueued: 0 };
|
|
3252
3355
|
const identity = { host_source_ref: registration.host_source_ref, host_session_ref: registration.host_session_ref, host_turn_ref: activeTask.host_turn_ref };
|
|
@@ -3451,7 +3554,8 @@ function expiration(now, retentionMs) {
|
|
|
3451
3554
|
|
|
3452
3555
|
// host/codex/src/codex-producer-runtime.ts
|
|
3453
3556
|
async function drainCodexProducerOnce(options) {
|
|
3454
|
-
const
|
|
3557
|
+
const promptPort = new HostRelayCurrentPromptPort(options.relay_endpoint, options.timeout_ms);
|
|
3558
|
+
const scan = await new CodexTranscriptWatcher({ outbox_dir: options.outbox_dir, producer_installation_ref: options.producer_installation_ref, register_current_prompt: (input) => promptPort.register(input) }).scanOnce();
|
|
3455
3559
|
const producer = new CodexProducer({ outbox_dir: options.outbox_dir, producer_installation_ref: options.producer_installation_ref, relay: new HostRelayIpcAdmissionPort(options.relay_endpoint, options.timeout_ms), ...options.producer_epoch === void 0 ? {} : { producer_epoch: options.producer_epoch }, ...options.now === void 0 ? {} : { now: options.now } });
|
|
3456
3560
|
return { scanned: scan.enqueued, ...await producer.drainOutbox() };
|
|
3457
3561
|
}
|