@effect-agent/storage-cloudflare 0.1.0-beta.39 → 0.1.0-beta.41
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/dist/index.d.mts +19903 -8
- package/dist/index.mjs +211 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -5
- package/src/do-memory-store.ts +51 -0
- package/src/index.ts +2 -0
- package/src/memory-protocol.ts +262 -0
- package/src/migrations.ts +3 -10
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { t as DoStorageFailpoint } from "./do-storage-failpoint-C-Qtchs7.mjs";
|
|
2
|
-
import { AbortCommand, AbortIntent, AcceptedEvent, AdmissionAdmitted, AdmissionConflict, AdmissionIndeterminate, AdmissionNotAdmitted, AdmissionRequest, AdmissionResolution, AdmissionResult, AppendConflict, AppendResult, ApprovalConflict, ApprovalDecision, ApprovalDecisionCommand, ApprovalDecisionIntent, AttachChildToReservationRequest, BeginChildBudgetReleaseRequest, CanonicalBatch, CanonicalRecord, CanonicalRecordEnvelope, CanonicalSequence, CheckpointRejected, ChildAttachmentSnapshot, ChildBudgetReservationRequest, ChildBudgetReservationSnapshot, ChildReservationConflict, ChildReservationStatus, ChildSettledNotification, ChildSettledOutcome, Claim, ClaimJoiningRequest, ClaimRequest, DEFAULT_OWNERSHIP_LEASE_DURATION, DefinitionDigests, DeliveryChange, Digest, EMPTY_TAIL_DIGEST, FenceRejected, FencedAppendRequest, InputAppliedMarker, JoinSnapshot, JoinedToHost, JoiningClaim, LedgerCapabilities, LedgerError, LoadCheckpointRequest, MarkInputAppliedRequest, MarkJoinedRequest, MarkReadyRequest, MarkUnknownRequest, ObservationOffset, OwnershipLost, OwnershipRenewal, OwnershipSnapshot, ParentLinkage, PersistedJson, ProducerEpoch, QueueSequence, RecordEnvelope, RecoverySnapshot, RecoverySnapshotRequest, ReleaseChildBudgetRequest, ReleaseOwnershipRequest, RenewOwnershipRequest, ReservedChildBudget, ReservedSettlement, RevertJoiningRequest, SaveCheckpointRequest, ScheduleCapacityError, ScheduleChange, ScheduleConflict, ScheduleDueCursor, ScheduleFailpoint, ScheduleId, ScheduleInstant, ScheduleKey, ScheduleNotFound, ScheduleOwner, SchedulePageRequest, ScheduleRecord, ScheduleStorageError, ScheduleStore, Settlement, SettlementConflict, SettlementFinalization, SettlementOutcome, SettlementReservation, SettlementReservationSnapshot, SourcePartition, SubmissionLedger, SubmissionLookup, SubmissionLookupById, SubmissionLookupByKey, SubmissionSnapshot, SubmissionState, SubscriptionDelivery, SubscriptionDeliveryKey, SubscriptionError, SubscriptionFailpoint, SubscriptionKey, SubscriptionLimits, SubscriptionName, SubscriptionRecord, SubscriptionScanCursors, SubscriptionStore, SuspendRequest, SuspensionReason, SuspensionSnapshot, ThreadCheckpoint, ThreadExport, ThreadExportRequest, ThreadMaterialization, ThreadNotMaterialized, ThreadObservation, ThreadRead, ThreadStore, ThreadStoreError, ThreadTail, ThreadTailRequest, UnknownResolution, UnknownResolutionCommand, UnknownResolutionConflict, UnknownResolutionIntent, applyScheduleChange, applySubscriptionDeliveryChange, defaultSchedulingLimits, digestCanonicalBatch, sameAcceptedEventIdentity, sameSourcePartition, scheduleDeadline, scheduleUsesCapacity, settlementFailureFromRecord, submissionAbortRecordId, subscriptionCanSelect, subscriptionDeliveryCanSelect, subscriptionDeliveryKeyString } from "@effect-agent/thread";
|
|
3
|
-
import { Clock, Context, Crypto, DateTime, Duration, Effect, Layer, Option, Predicate, Ref, Result, Schema, Stream } from "effect";
|
|
2
|
+
import { AbortCommand, AbortIntent, AcceptedEvent, AdmissionAdmitted, AdmissionConflict, AdmissionIndeterminate, AdmissionNotAdmitted, AdmissionRequest, AdmissionResolution, AdmissionResult, AppendConflict, AppendResult, ApprovalConflict, ApprovalDecision, ApprovalDecisionCommand, ApprovalDecisionIntent, AttachChildToReservationRequest, BeginChildBudgetReleaseRequest, CanonicalBatch, CanonicalRecord, CanonicalRecordEnvelope, CanonicalSequence, CheckpointRejected, ChildAttachmentSnapshot, ChildBudgetReservationRequest, ChildBudgetReservationSnapshot, ChildReservationConflict, ChildReservationStatus, ChildSettledNotification, ChildSettledOutcome, Claim, ClaimJoiningRequest, ClaimRequest, DEFAULT_OWNERSHIP_LEASE_DURATION, DefinitionDigests, DeliveryChange, Digest, EMPTY_TAIL_DIGEST, FenceRejected, FencedAppendRequest, InputAppliedMarker, JoinSnapshot, JoinedToHost, JoiningClaim, LedgerCapabilities, LedgerError, LoadCheckpointRequest, MarkInputAppliedRequest, MarkJoinedRequest, MarkReadyRequest, MarkUnknownRequest, ObservationOffset, OwnershipLost, OwnershipRenewal, OwnershipSnapshot, ParentLinkage, PersistedJson, Principal, ProducerEpoch, QueueSequence, RecordEnvelope, RecoverySnapshot, RecoverySnapshotRequest, ReleaseChildBudgetRequest, ReleaseOwnershipRequest, RenewOwnershipRequest, ReservedChildBudget, ReservedSettlement, RevertJoiningRequest, SaveCheckpointRequest, ScheduleCapacityError, ScheduleChange, ScheduleConflict, ScheduleDueCursor, ScheduleFailpoint, ScheduleId, ScheduleInstant, ScheduleKey, ScheduleNotFound, ScheduleOwner, SchedulePageRequest, ScheduleRecord, ScheduleStorageError, ScheduleStore, Settlement, SettlementConflict, SettlementFinalization, SettlementOutcome, SettlementReservation, SettlementReservationSnapshot, SourcePartition, SubmissionLedger, SubmissionLookup, SubmissionLookupById, SubmissionLookupByKey, SubmissionSnapshot, SubmissionState, SubscriptionDelivery, SubscriptionDeliveryKey, SubscriptionError, SubscriptionFailpoint, SubscriptionKey, SubscriptionLimits, SubscriptionName, SubscriptionRecord, SubscriptionScanCursors, SubscriptionStore, SuspendRequest, SuspensionReason, SuspensionSnapshot, ThreadCheckpoint, ThreadExport, ThreadExportRequest, ThreadMaterialization, ThreadNotMaterialized, ThreadObservation, ThreadRead, ThreadStore, ThreadStoreError, ThreadTail, ThreadTailRequest, UnknownResolution, UnknownResolutionCommand, UnknownResolutionConflict, UnknownResolutionIntent, applyScheduleChange, applySubscriptionDeliveryChange, defaultSchedulingLimits, digestCanonicalBatch, sameAcceptedEventIdentity, sameSourcePartition, scheduleDeadline, scheduleUsesCapacity, settlementFailureFromRecord, submissionAbortRecordId, subscriptionCanSelect, subscriptionDeliveryCanSelect, subscriptionDeliveryKeyString } from "@effect-agent/thread";
|
|
3
|
+
import { Clock, Context, Crypto, DateTime, Duration, Effect, Encoding, Layer, Option, Predicate, Ref, Result, Schema, Stream } from "effect";
|
|
4
4
|
import { SqliteClient, SqliteMigrator } from "@effect/sql-sqlite-do";
|
|
5
5
|
import * as SqlClient from "effect/unstable/sql/SqlClient";
|
|
6
6
|
import { BrowserCrypto } from "@effect/platform-browser";
|
|
7
7
|
import { SqlError } from "effect/unstable/sql/SqlError";
|
|
8
|
+
import { MemoryAccess, MemoryConflict, MemoryDocument, MemoryIndexError, MemoryIndexSearch, MemoryLookup, MemoryMutationFailpoint, MemoryMutationFailure, MemoryNamespace, MemoryOperationConflict, MemoryRecallError, MemoryRecallLimits, MemoryStorageError, MemoryWithdrawn, MemoryWrite, MemoryWriter, SemanticCandidateLimits, SemanticCandidateResult, SemanticMemoryError, SemanticMemoryProfile, revalidateMemoryLookup, revalidateSemanticMemoryCandidates } from "@effect-agent/core";
|
|
9
|
+
import { SqlMemoryLimits, memoryStoreLayerWithFailpoints } from "@effect-agent/thread/sql-memory";
|
|
8
10
|
//#region src/errors.ts
|
|
9
11
|
/** The Durable Object's SQLite storage uses a private-development format this adapter cannot read. */
|
|
10
12
|
var DoStorageCompatibilityError = class extends Schema.TaggedError()("DoStorageCompatibilityError", {
|
|
@@ -146,18 +148,11 @@ var DoStorageFailpointError = class extends Schema.TaggedError()("DoStorageFailp
|
|
|
146
148
|
};
|
|
147
149
|
//#endregion
|
|
148
150
|
//#region src/migrations.ts
|
|
149
|
-
/**
|
|
150
|
-
* The exact-or-fresh storage version recorded in `effect_agent_meta`. Cloudflare is a fresh
|
|
151
|
-
* platform, so there is exactly ONE migration carrying the complete current schema — no
|
|
152
|
-
* v1→v4 history to replay (deployment spec §9: no rolling data-version promise during
|
|
153
|
-
* private development).
|
|
154
|
-
*/
|
|
151
|
+
/** The current storage version recorded in `effect_agent_meta`. */
|
|
155
152
|
const CurrentDoStorageVersion = 2;
|
|
156
153
|
/**
|
|
157
|
-
* The Thread Durable Object schema
|
|
158
|
-
*
|
|
159
|
-
* into their final shape) so the shared conformance suites and crash-matrix rows address
|
|
160
|
-
* identical durable state. Two DC-specific additions:
|
|
154
|
+
* The Thread Durable Object schema shares its thread and ledger tables with Node/SQLite.
|
|
155
|
+
* Schedules and subscriptions use separate Durable Objects. Two DC-specific additions:
|
|
161
156
|
*
|
|
162
157
|
* 1. `effect_agent_meta` replaces `PRAGMA user_version` as the exact-or-fresh version gate —
|
|
163
158
|
* a meta table is portable regardless of which PRAGMAs Durable Object SQL storage allows.
|
|
@@ -393,8 +388,6 @@ const BoundedStoredText$1 = Schema.String.check(Schema.isMaxLength(2e6));
|
|
|
393
388
|
const BoundedIdentifier$1 = Schema.NonEmptyString.check(Schema.isMaxLength(1024));
|
|
394
389
|
const MAX_RECORDS_PER_THREAD = 65536;
|
|
395
390
|
const MAX_IDENTIFIER_LENGTH$1 = 1024;
|
|
396
|
-
/** Durable Object SQL storage allows at most 100 bound parameters per statement. */
|
|
397
|
-
const MAX_BOUND_PARAMETERS = 100;
|
|
398
391
|
const isSqlError = Schema.is(SqlError);
|
|
399
392
|
const storedTextBytes = (value) => new TextEncoder().encode(value).byteLength;
|
|
400
393
|
const chunked = (values, size) => {
|
|
@@ -730,7 +723,7 @@ const makeJournal = (sql, failpoint, maxStoredValueBytes) => {
|
|
|
730
723
|
message: `Thread record limit ${MAX_RECORDS_PER_THREAD} would be exceeded.`
|
|
731
724
|
});
|
|
732
725
|
const existingRecords = [];
|
|
733
|
-
for (const chunk of chunked(recordIds,
|
|
726
|
+
for (const chunk of chunked(recordIds, 90)) {
|
|
734
727
|
const existingRecordRows = yield* sql`
|
|
735
728
|
SELECT
|
|
736
729
|
thread_id,
|
|
@@ -1083,7 +1076,7 @@ var DoStorageConfigValue = class extends Schema.Class("@effect-agent/storage-clo
|
|
|
1083
1076
|
var DoStorageConfig = class extends Context.Service()("@effect-agent/storage-cloudflare/DoStorageConfig") {};
|
|
1084
1077
|
//#endregion
|
|
1085
1078
|
//#region src/do-thread-store.ts
|
|
1086
|
-
const OffsetText = Schema.String.check(Schema.isMaxLength(
|
|
1079
|
+
const OffsetText = Schema.String.check(Schema.isMaxLength(4096));
|
|
1087
1080
|
const DO_OFFSET_PREFIX = "effect-agent-do@1:";
|
|
1088
1081
|
const ZERO_CANONICAL_SEQUENCE = Schema.decodeSync(CanonicalSequence)(0);
|
|
1089
1082
|
const isDigest = Schema.is(Digest);
|
|
@@ -2385,7 +2378,8 @@ const makeServices$1 = Effect.fn("DoSubmissionLedger.makeServices")(function* ()
|
|
|
2385
2378
|
submissionId: validated.submissionId,
|
|
2386
2379
|
existingOutcome: reservation.value.outcome
|
|
2387
2380
|
});
|
|
2388
|
-
const
|
|
2381
|
+
const reservationRecord = yield* decodeRecordEnvelopeText(reservation.value.record_json).pipe(Effect.mapError((error) => corruptionFailure(operation, "effect_agent_settlement_reservations", validated.submissionId, error.message)));
|
|
2382
|
+
const settlementFailure = settlementFailureFromRecord(reservationRecord);
|
|
2389
2383
|
if (reservation.value.outcome === "failed" !== (settlementFailure !== void 0)) return yield* corruptionFailure(operation, "effect_agent_settlement_reservations", validated.submissionId, "The reserved outcome and canonical failure diagnostic disagree.");
|
|
2390
2384
|
const submission = yield* requireSubmission(operation, validated.submissionId);
|
|
2391
2385
|
if (submission.state === "settled") {
|
|
@@ -4042,7 +4036,8 @@ const makeSubscriptionStore = Effect.fn("SqliteSubscriptionStore.make")(function
|
|
|
4042
4036
|
return false;
|
|
4043
4037
|
}
|
|
4044
4038
|
yield* failpoint.hit("subscription:catch-up:before");
|
|
4045
|
-
|
|
4039
|
+
const effectiveNowMillis = Math.max(nowMillis, yield* Clock.currentTimeMillis);
|
|
4040
|
+
if (!subscriptionCanSelect(record, accepted, effectiveNowMillis, true)) return yield* error("conflict", "catch-up-eligibility");
|
|
4046
4041
|
if ((yield* count(sql`SELECT COUNT(*) AS count FROM effect_agent_subscription_deliveries WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}`, "count deliveries")) >= limits.maxDeliveries) return yield* error("capacity", "deliveries");
|
|
4047
4042
|
if ((yield* count(sql`SELECT COUNT(*) AS count FROM effect_agent_subscription_deliveries WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND owner_id=${record.key.ownerId}`, "count owner deliveries")) >= limits.maxDeliveriesPerOwner) return yield* error("capacity", "owner-deliveries");
|
|
4048
4043
|
yield* insertDelivery(delivery);
|
|
@@ -4276,7 +4271,7 @@ const doSubscriptionStoreLayer = (partition) => Layer.effectContext(makeSubscrip
|
|
|
4276
4271
|
const MAX_PORT_DIAGNOSTIC_LENGTH = 4096;
|
|
4277
4272
|
const BoundedDiagnostic = Schema.String.check(Schema.isMaxLength(MAX_PORT_DIAGNOSTIC_LENGTH));
|
|
4278
4273
|
/** Truncate a diagnostic string to the protocol's bounded diagnostic length. */
|
|
4279
|
-
const boundPortDiagnostic = (value) => value.length > 4096 ? `${value.slice(0,
|
|
4274
|
+
const boundPortDiagnostic = (value) => value.length > 4096 ? `${value.slice(0, 4093)}...` : value;
|
|
4280
4275
|
/**
|
|
4281
4276
|
* The envelope itself could not be honored: the receiving Object could not decode the
|
|
4282
4277
|
* request, or a response could not be encoded/decoded. It never carries port semantics —
|
|
@@ -4484,7 +4479,8 @@ const crossThreadStoreError = (operation, target) => ThreadStoreError.make({
|
|
|
4484
4479
|
});
|
|
4485
4480
|
const makeTransportCall = (transport) => Effect.fn("DoPortRouting.transportCall")(function* (target, call) {
|
|
4486
4481
|
const encoded = yield* encodePortRequest(call).pipe(Effect.mapError((error) => PortProtocolError.make({ message: boundPortDiagnostic(`The port request could not be encoded: ${error.message}`) })));
|
|
4487
|
-
|
|
4482
|
+
const raw = yield* transport.call(target, encoded);
|
|
4483
|
+
return yield* decodePortResponse(raw).pipe(Effect.mapError((error) => PortProtocolError.make({ message: boundPortDiagnostic(`The port response could not be decoded: ${error.message}`) })));
|
|
4488
4484
|
});
|
|
4489
4485
|
const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServices")(function* (options) {
|
|
4490
4486
|
const local = yield* SubmissionLedger;
|
|
@@ -4757,9 +4753,202 @@ const encodedProtocolFailure = (message) => ({
|
|
|
4757
4753
|
* transport never has to interpret exceptions as protocol answers.
|
|
4758
4754
|
*/
|
|
4759
4755
|
const handleEncodedPortRequest = Effect.fn("DoPortRouting.handleEncodedPortRequest")(function* (encoded) {
|
|
4760
|
-
|
|
4756
|
+
const response = yield* decodePortRequest(encoded).pipe(Effect.flatMap(executePortRequest), Effect.catch((error) => Effect.succeed(PortFailed.make({ failure: PortProtocolError.make({ message: boundPortDiagnostic(`The port request could not be decoded: ${error.message}`) }) }))));
|
|
4757
|
+
return yield* encodePortResponse(response).pipe(Effect.catch((error) => Effect.succeed(encodedProtocolFailure(`The port response could not be encoded: ${error.message}`))));
|
|
4758
|
+
});
|
|
4759
|
+
//#endregion
|
|
4760
|
+
//#region src/do-memory-store.ts
|
|
4761
|
+
var DoMemoryStorageLimits = class extends Schema.Class("@effect-agent/storage-cloudflare/DoMemoryStorageLimits")({
|
|
4762
|
+
maxRowBytes: Schema.Int.check(Schema.isBetween({
|
|
4763
|
+
minimum: 1,
|
|
4764
|
+
maximum: 19e5
|
|
4765
|
+
})),
|
|
4766
|
+
maxStorageBytes: Schema.Int.check(Schema.isBetween({
|
|
4767
|
+
minimum: 1,
|
|
4768
|
+
maximum: 536870912
|
|
4769
|
+
})),
|
|
4770
|
+
maxDocuments: Schema.Int.check(Schema.isBetween({
|
|
4771
|
+
minimum: 1,
|
|
4772
|
+
maximum: 1e5
|
|
4773
|
+
})),
|
|
4774
|
+
maxReceipts: Schema.Int.check(Schema.isBetween({
|
|
4775
|
+
minimum: 1,
|
|
4776
|
+
maximum: 1e6
|
|
4777
|
+
}))
|
|
4778
|
+
}) {};
|
|
4779
|
+
const defaultDoMemoryStorageLimits = DoMemoryStorageLimits.make({
|
|
4780
|
+
maxRowBytes: 19e5,
|
|
4781
|
+
maxStorageBytes: 536870912,
|
|
4782
|
+
maxDocuments: 1e4,
|
|
4783
|
+
maxReceipts: 1e5
|
|
4784
|
+
});
|
|
4785
|
+
/**
|
|
4786
|
+
* Local memory only, without Thread tables. Keep one SQL client per owner and pass the
|
|
4787
|
+
* full storage handle: sql-only handles cannot provide atomic receipts and revisions.
|
|
4788
|
+
* Byte limits conservatively count encoded rows, not SQLite page/index overhead.
|
|
4789
|
+
*/
|
|
4790
|
+
const doMemoryStoreLayerWithFailpoints = (storage, limits = defaultDoMemoryStorageLimits) => Layer.unwrap(Schema.decodeUnknownEffect(DoMemoryStorageLimits)(limits).pipe(Effect.mapError(() => MemoryStorageError.make({
|
|
4791
|
+
operation: "memory storage limits",
|
|
4792
|
+
reason: "invalid-input"
|
|
4793
|
+
})), Effect.map((validated) => memoryStoreLayerWithFailpoints.pipe(Layer.provide(Layer.succeed(SqlMemoryLimits, validated)), Layer.provide(SqliteClient.layer({ storage }))))));
|
|
4794
|
+
const doMemoryStoreLayer = (storage, limits = defaultDoMemoryStorageLimits) => doMemoryStoreLayerWithFailpoints(storage, limits).pipe(Layer.provide(MemoryMutationFailpoint.layer));
|
|
4795
|
+
//#endregion
|
|
4796
|
+
//#region src/memory-protocol.ts
|
|
4797
|
+
var MemoryRpcError = class extends Schema.TaggedError()("MemoryRpcError", { reason: Schema.Literals([
|
|
4798
|
+
"denied",
|
|
4799
|
+
"protocol",
|
|
4800
|
+
"budget",
|
|
4801
|
+
"timeout",
|
|
4802
|
+
"unavailable"
|
|
4803
|
+
]) }) {};
|
|
4804
|
+
var MemoryRpcLimits = class extends Schema.Class("@effect-agent/storage-cloudflare/MemoryRpcLimits")({
|
|
4805
|
+
maxRequestBytes: Schema.Int.check(Schema.isBetween({
|
|
4806
|
+
minimum: 256,
|
|
4807
|
+
maximum: 4194304
|
|
4808
|
+
})),
|
|
4809
|
+
maxResponseBytes: Schema.Int.check(Schema.isBetween({
|
|
4810
|
+
minimum: 256,
|
|
4811
|
+
maximum: 16777216
|
|
4812
|
+
})),
|
|
4813
|
+
maxSourceBytes: Schema.Int.check(Schema.isBetween({
|
|
4814
|
+
minimum: 1,
|
|
4815
|
+
maximum: 67108864
|
|
4816
|
+
})),
|
|
4817
|
+
maxSources: MemoryRecallLimits.fields.maxSources,
|
|
4818
|
+
timeoutMillis: MemoryRecallLimits.fields.timeoutMillis
|
|
4819
|
+
}) {};
|
|
4820
|
+
const defaultMemoryRpcLimits = MemoryRpcLimits.make({
|
|
4821
|
+
maxRequestBytes: 1048576,
|
|
4822
|
+
maxResponseBytes: 4194304,
|
|
4823
|
+
maxSourceBytes: 16777216,
|
|
4824
|
+
maxSources: 16,
|
|
4825
|
+
timeoutMillis: 1e4
|
|
4826
|
+
});
|
|
4827
|
+
const RequestFields = {
|
|
4828
|
+
version: Schema.Literal(1),
|
|
4829
|
+
access: MemoryAccess.Wire,
|
|
4830
|
+
/** Host-authenticated identity, never copied from model input. The owner still authorizes it. */
|
|
4831
|
+
principal: Principal,
|
|
4832
|
+
deadlineMillis: Schema.Finite.check(Schema.isGreaterThanOrEqualTo(0))
|
|
4833
|
+
};
|
|
4834
|
+
const RevalidateRequest = Schema.TaggedStruct("Revalidate", {
|
|
4835
|
+
...RequestFields,
|
|
4836
|
+
lookup: MemoryLookup,
|
|
4837
|
+
limits: MemoryRecallLimits
|
|
4838
|
+
});
|
|
4839
|
+
const ChangeRequest = Schema.TaggedStruct("Change", {
|
|
4840
|
+
...RequestFields,
|
|
4841
|
+
write: MemoryWrite.Wire
|
|
4842
|
+
});
|
|
4843
|
+
const SemanticRequest = Schema.TaggedStruct("RevalidateSemantic", {
|
|
4844
|
+
...RequestFields,
|
|
4845
|
+
found: MemoryIndexSearch.Wire,
|
|
4846
|
+
profile: SemanticMemoryProfile,
|
|
4847
|
+
limits: SemanticCandidateLimits
|
|
4848
|
+
});
|
|
4849
|
+
const MemoryOwnerRequest = Schema.Union([
|
|
4850
|
+
RevalidateRequest,
|
|
4851
|
+
ChangeRequest,
|
|
4852
|
+
SemanticRequest
|
|
4853
|
+
]);
|
|
4854
|
+
const MemoryOwnerFailure = Schema.Union([
|
|
4855
|
+
MemoryRpcError,
|
|
4856
|
+
MemoryStorageError,
|
|
4857
|
+
MemoryRecallError,
|
|
4858
|
+
MemoryConflict,
|
|
4859
|
+
MemoryWithdrawn,
|
|
4860
|
+
MemoryOperationConflict,
|
|
4861
|
+
MemoryMutationFailure,
|
|
4862
|
+
MemoryIndexError,
|
|
4863
|
+
SemanticMemoryError
|
|
4864
|
+
]);
|
|
4865
|
+
const MemoryOwnerResponse = Schema.Union([
|
|
4866
|
+
Schema.TaggedStruct("Lookup", {
|
|
4867
|
+
access: MemoryAccess.Wire,
|
|
4868
|
+
lookup: MemoryLookup
|
|
4869
|
+
}),
|
|
4870
|
+
Schema.TaggedStruct("Changed", {
|
|
4871
|
+
access: MemoryAccess.Wire,
|
|
4872
|
+
document: MemoryDocument.Wire
|
|
4873
|
+
}),
|
|
4874
|
+
Schema.TaggedStruct("Semantic", {
|
|
4875
|
+
access: MemoryAccess.Wire,
|
|
4876
|
+
result: SemanticCandidateResult
|
|
4877
|
+
}),
|
|
4878
|
+
Schema.TaggedStruct("Failed", { failure: MemoryOwnerFailure })
|
|
4879
|
+
]);
|
|
4880
|
+
/** Fail-closed application policy. Authorize the namespace, principal, scope, and full command. */
|
|
4881
|
+
var MemoryOwnerAuthorizer = class extends Context.Service()("@effect-agent/storage-cloudflare/MemoryOwnerAuthorizer") {};
|
|
4882
|
+
/** Canonical namespace derived from this object's idFromName identity, never its request. */
|
|
4883
|
+
var MemoryOwnerIdentity = class extends Context.Service()("@effect-agent/storage-cloudflare/MemoryOwnerIdentity") {};
|
|
4884
|
+
const memoryWireBytes = (text) => Encoding.encodeHex(text).length / 2;
|
|
4885
|
+
const decodeMemoryWire = Effect.fn("decodeMemoryWire")(function* (schema, raw, maxBytes) {
|
|
4886
|
+
const text = yield* Schema.decodeUnknownEffect(Schema.String)(raw).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })));
|
|
4887
|
+
if (text.length > maxBytes || memoryWireBytes(text) > maxBytes) return yield* MemoryRpcError.make({ reason: "budget" });
|
|
4888
|
+
return yield* Schema.decodeEffect(Schema.fromJsonString(schema))(text).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })));
|
|
4889
|
+
});
|
|
4890
|
+
const encodeMemoryWire = Effect.fn("encodeMemoryWire")(function* (schema, value, maxBytes) {
|
|
4891
|
+
const encoded = yield* Schema.encodeEffect(Schema.fromJsonString(schema))(value).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })));
|
|
4892
|
+
if (encoded.length > maxBytes || memoryWireBytes(encoded) > maxBytes) return yield* MemoryRpcError.make({ reason: "budget" });
|
|
4893
|
+
return encoded;
|
|
4894
|
+
});
|
|
4895
|
+
/** One local read per distinct candidate source, with no per-document network calls. */
|
|
4896
|
+
const handleMemoryOwnerRequest = Effect.fn("MemoryOwner.handleRequest")(function* (raw, limits = defaultMemoryRpcLimits) {
|
|
4897
|
+
const result = yield* Effect.gen(function* () {
|
|
4898
|
+
limits = yield* Schema.decodeUnknownEffect(MemoryRpcLimits)(limits).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })));
|
|
4899
|
+
const request = yield* decodeMemoryWire(MemoryOwnerRequest, raw, limits.maxRequestBytes);
|
|
4900
|
+
const { namespace } = yield* MemoryOwnerIdentity;
|
|
4901
|
+
if (!MemoryNamespace.equals(namespace, request.access.namespace) || request._tag === "Change" && !MemoryNamespace.equals(namespace, request.write.key.namespace) || request._tag === "RevalidateSemantic" && request.found.candidates.some((candidate) => !MemoryNamespace.equals(namespace, candidate.key.namespace))) return yield* MemoryRpcError.make({ reason: "denied" });
|
|
4902
|
+
const remaining = Math.min(limits.timeoutMillis, request.deadlineMillis - (yield* Clock.currentTimeMillis));
|
|
4903
|
+
if (remaining <= 0) return yield* MemoryRpcError.make({ reason: "timeout" });
|
|
4904
|
+
return yield* Effect.gen(function* () {
|
|
4905
|
+
yield* (yield* MemoryOwnerAuthorizer).authorize(request);
|
|
4906
|
+
if (request._tag === "Change") {
|
|
4907
|
+
const writer = yield* MemoryWriter;
|
|
4908
|
+
return {
|
|
4909
|
+
_tag: "Changed",
|
|
4910
|
+
access: request.access,
|
|
4911
|
+
document: yield* writer.change(request.write)
|
|
4912
|
+
};
|
|
4913
|
+
}
|
|
4914
|
+
if (request._tag === "RevalidateSemantic") {
|
|
4915
|
+
if (new Set(request.found.candidates.map((candidate) => candidate.key.id)).size > limits.maxSources) return yield* MemoryRpcError.make({ reason: "budget" });
|
|
4916
|
+
const result = yield* revalidateSemanticMemoryCandidates(request.found, request.access, request.profile, {
|
|
4917
|
+
...request.limits,
|
|
4918
|
+
maxSourceBytes: Math.min(limits.maxSourceBytes, request.limits.maxSourceBytes ?? 16777216),
|
|
4919
|
+
maxOutputBytes: Math.min(limits.maxResponseBytes, request.limits.maxOutputBytes ?? 16777216)
|
|
4920
|
+
});
|
|
4921
|
+
return {
|
|
4922
|
+
_tag: "Semantic",
|
|
4923
|
+
access: request.access,
|
|
4924
|
+
result
|
|
4925
|
+
};
|
|
4926
|
+
}
|
|
4927
|
+
if ((request.lookup._tag === "Found" ? new Set(request.lookup.passages.map((passage) => passage.source.id)).size : 0) > Math.min(limits.maxSources, request.limits.maxSources)) return yield* MemoryRpcError.make({ reason: "budget" });
|
|
4928
|
+
const lookup = yield* revalidateMemoryLookup(request.lookup, request.access, {
|
|
4929
|
+
maxSourceBytes: limits.maxSourceBytes,
|
|
4930
|
+
maxInputBytes: Math.min(limits.maxSourceBytes, request.limits.maxInputBytes ?? 16777216)
|
|
4931
|
+
});
|
|
4932
|
+
return {
|
|
4933
|
+
_tag: "Lookup",
|
|
4934
|
+
access: request.access,
|
|
4935
|
+
lookup
|
|
4936
|
+
};
|
|
4937
|
+
}).pipe(Effect.scoped, Effect.timeoutOrElse({
|
|
4938
|
+
duration: remaining,
|
|
4939
|
+
orElse: () => Effect.fail(MemoryRpcError.make({ reason: "timeout" }))
|
|
4940
|
+
}));
|
|
4941
|
+
}).pipe(Effect.flatMap((response) => encodeMemoryWire(MemoryOwnerResponse, response, limits.maxResponseBytes)), Effect.result);
|
|
4942
|
+
if (result._tag === "Success") return result.success;
|
|
4943
|
+
return yield* encodeMemoryWire(MemoryOwnerResponse, {
|
|
4944
|
+
_tag: "Failed",
|
|
4945
|
+
failure: result.failure
|
|
4946
|
+
}, limits.maxResponseBytes).pipe(Effect.catch(() => Schema.encodeEffect(Schema.fromJsonString(MemoryOwnerResponse))({
|
|
4947
|
+
_tag: "Failed",
|
|
4948
|
+
failure: MemoryRpcError.make({ reason: "budget" })
|
|
4949
|
+
}).pipe(Effect.orDie)));
|
|
4761
4950
|
});
|
|
4762
4951
|
//#endregion
|
|
4763
|
-
export { CurrentDoStorageVersion, DEFAULT_MAX_STORED_VALUE_BYTES, DoAppendConflict, DoCheckpointConflict, DoFenceRejected, DoLedgerError, DoScheduleAlarmControl, DoScheduleTransaction, DoStorageCompatibilityError, DoStorageConfig, DoStorageConfigValue, DoStorageCorruptionError, DoStorageError, DoStorageFailpoint, DoStorageFailpointError, DoStorageFailpointLocation, DoSubscriptionAlarmControl, DoSubscriptionTransaction, DoValueBoundExceeded, LedgerAdmitCall, LedgerAdmitResult, LedgerLookupCall, LedgerLookupResult, LedgerMarkReadyCall, LedgerMarkReadyResult, LedgerRecordChildSettledCall, LedgerRecordChildSettledResult, LedgerRequestAbortCall, LedgerRequestAbortResult, LedgerResolveAdmissionCall, LedgerResolveAdmissionResult, MAX_PORT_DIAGNOSTIC_LENGTH, PortFailed, PortFailure, PortProtocolError, PortRequest, PortResponse, PortResult, PortSucceeded, PortTransportError, StoreAppendCall, StoreAppendResult, StoreExportCall, StoreExportResult, StoreInspectTailCall, StoreInspectTailResult, StoreMaterializeCall, StoreMaterializeResult, StoreReadPageCall, StoreReadPageResult, ThreadPortTransport, boundPortDiagnostic, decodePortRequest, decodePortResponse, doSubscriptionStoreLayer, encodePortRequest, encodePortResponse, executePortRequest, handleEncodedPortRequest, layer, ledgerLayer, observationOffsetAt, portTransportFailure, routedSubmissionLedgerLayer, routedThreadStoreLayer, scheduleStoreLayer, storageConfigLayer, storageFailpointLayer, submissionLedgerLayer, threadStoreLayer };
|
|
4952
|
+
export { CurrentDoStorageVersion, DEFAULT_MAX_STORED_VALUE_BYTES, DoAppendConflict, DoCheckpointConflict, DoFenceRejected, DoLedgerError, DoMemoryStorageLimits, DoScheduleAlarmControl, DoScheduleTransaction, DoStorageCompatibilityError, DoStorageConfig, DoStorageConfigValue, DoStorageCorruptionError, DoStorageError, DoStorageFailpoint, DoStorageFailpointError, DoStorageFailpointLocation, DoSubscriptionAlarmControl, DoSubscriptionTransaction, DoValueBoundExceeded, LedgerAdmitCall, LedgerAdmitResult, LedgerLookupCall, LedgerLookupResult, LedgerMarkReadyCall, LedgerMarkReadyResult, LedgerRecordChildSettledCall, LedgerRecordChildSettledResult, LedgerRequestAbortCall, LedgerRequestAbortResult, LedgerResolveAdmissionCall, LedgerResolveAdmissionResult, MAX_PORT_DIAGNOSTIC_LENGTH, MemoryOwnerAuthorizer, MemoryOwnerFailure, MemoryOwnerIdentity, MemoryOwnerRequest, MemoryOwnerResponse, MemoryRpcError, MemoryRpcLimits, PortFailed, PortFailure, PortProtocolError, PortRequest, PortResponse, PortResult, PortSucceeded, PortTransportError, StoreAppendCall, StoreAppendResult, StoreExportCall, StoreExportResult, StoreInspectTailCall, StoreInspectTailResult, StoreMaterializeCall, StoreMaterializeResult, StoreReadPageCall, StoreReadPageResult, ThreadPortTransport, boundPortDiagnostic, decodeMemoryWire, decodePortRequest, decodePortResponse, defaultDoMemoryStorageLimits, defaultMemoryRpcLimits, doMemoryStoreLayer, doMemoryStoreLayerWithFailpoints, doSubscriptionStoreLayer, encodeMemoryWire, encodePortRequest, encodePortResponse, executePortRequest, handleEncodedPortRequest, handleMemoryOwnerRequest, layer, ledgerLayer, memoryWireBytes, observationOffsetAt, portTransportFailure, routedSubmissionLedgerLayer, routedThreadStoreLayer, scheduleStoreLayer, storageConfigLayer, storageFailpointLayer, submissionLedgerLayer, threadStoreLayer };
|
|
4764
4953
|
|
|
4765
4954
|
//# sourceMappingURL=index.mjs.map
|