@framers/agentos-ext-account-sources 0.1.0 → 0.2.0

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @framers/agentos-ext-account-sources
2
2
 
3
- A person's own accounts as sources. This library defines `AccountSourceConnector` and the `SourceRef` every passage carries, with helpers for line ranges, links, bounded body reads and requests under the shared public-sources limiter.
3
+ A person's own accounts as sources. This library defines `AccountSourceConnector` and the `SourceRef` every passage carries, with helpers for line ranges, links, bounded body reads, requests under the shared public-sources limiter and the cache lifetime of a read.
4
4
 
5
5
  Install `@framers/agentos-ext-account-sources` with its peer `@framers/agentos` 0.10.40 or later. Node.js 20.19 or later is required. The runtime dependency is `@framers/agentos-ext-public-sources`.
6
6
 
@@ -65,6 +65,60 @@ async function readSource(url: string, signal?: AbortSignal): Promise<Uint8Array
65
65
  }
66
66
  ```
67
67
 
68
+ ## Cache retention
69
+
70
+ ```ts
71
+ import { decideSourceCache, type SourceCacheDecision, type SourceCachePermission } from '@framers/agentos-ext-account-sources';
72
+
73
+ /** Decides whether a response whose read began at `readStartedAt` may be stored, and until when. */
74
+ function cacheDecision(
75
+ response: Response,
76
+ permission: SourceCachePermission | null,
77
+ readStartedAt: number,
78
+ windowExpiresAt: number,
79
+ ): SourceCacheDecision {
80
+ return decideSourceCache({
81
+ permission,
82
+ maximumCacheMs: 86_400_000,
83
+ readStartedAt,
84
+ receivedAt: Date.now(),
85
+ windowExpiresAt,
86
+ headers: {
87
+ cacheControl: response.headers.get('cache-control'),
88
+ date: response.headers.get('date'),
89
+ age: response.headers.get('age'),
90
+ expires: response.headers.get('expires'),
91
+ },
92
+ });
93
+ }
94
+ ```
95
+
96
+ `decideSourceCache(input)` answers `{ kind: 'cache', expiresAt, evidenceId }` or `{ kind: 'skip', reason }`. Its input holds the permission record, the host's maximum lifetime, three times in epoch milliseconds and four response headers; it takes no response body, URL or token.
97
+
98
+ `permission` is the host's record of an approved retention policy: an opaque `evidenceId` and a `retentionMs`. The library applies the record; it does not establish that a provider allows caching. A missing record, a blank `evidenceId` or a `retentionMs` that is not a positive safe integer answers `not_permitted`, whatever the headers allow.
99
+
100
+ `expiresAt` is the earliest of:
101
+
102
+ - `readStartedAt` plus the smaller of `retentionMs` and `maximumCacheMs`, less the response's `Age`;
103
+ - `windowExpiresAt`, the end of the retained material's window (the earliest end when a read holds several items);
104
+ - the `max-age` and `s-maxage` lifetimes, counted from `receivedAt` and reduced by the corrected age of [RFC 9111, section 4.2.3](https://www.rfc-editor.org/rfc/rfc9111#section-4.2.3): the larger of the age the `Date` header implies and `Age` plus the time the read took;
105
+ - the `Expires` lifetime (its distance from `Date`, or from `readStartedAt` when `Date` is absent), counted and reduced the same way, and the `Expires` time itself.
106
+
107
+ A skip carries one of these reasons:
108
+
109
+ | Reason | When |
110
+ |---|---|
111
+ | `not_permitted` | No permission record, a blank `evidenceId`, or a `retentionMs` that is not a positive safe integer |
112
+ | `no_store` | `Cache-Control` holds `no-store` |
113
+ | `revalidation_required` | `Cache-Control` holds `no-cache`, with or without field names |
114
+ | `invalid_cache_header` | A malformed or repeated `Cache-Control` directive; a `max-age` or `s-maxage` without a whole number of seconds or past the safe-integer range; an `Age` that is not a whole number of seconds or is past the safe-integer range; a `Date` or `Expires` before 1970 or outside the IMF-fixdate form of [RFC 9110, section 5.6.7](https://www.rfc-editor.org/rfc/rfc9110#section-5.6.7), exactly as `Date.prototype.toUTCString()` writes it (`Tue, 14 Nov 2023 22:13:20 GMT`) |
115
+ | `invalid_bounds` | A clock value that is not a nonnegative safe integer, a `receivedAt` before `readStartedAt`, a `maximumCacheMs` that is not a positive safe integer, or a lifetime past the safe-integer range |
116
+ | `expired` | The lifetime ends at or before `receivedAt` |
117
+
118
+ Directive names match in any case and values may be quoted. Other directives, such as `private` and `immutable`, neither grant nor extend a lifetime. The obsolete HTTP date forms are refused rather than parsed.
119
+
120
+ A skip stores nothing: record its reason and keep no content. Store `expiresAt` with the content and check it on every read. Neither a later sync checkpoint nor a second call with the old response extends it; a new read takes a new decision.
121
+
68
122
  ## License
69
123
 
70
124
  Apache-2.0. This pack carries a copy of the repository's license.
@@ -0,0 +1,39 @@
1
+ /** Host-verified permission; this module does not establish provider authorization. */
2
+ export interface SourceCachePermission {
3
+ readonly evidenceId: string;
4
+ readonly retentionMs: number;
5
+ }
6
+ /** Cache metadata only; no request URL, token or response content enters the policy. */
7
+ export interface SourceCacheHeaders {
8
+ readonly cacheControl: string | null;
9
+ readonly date: string | null;
10
+ readonly age: string | null;
11
+ readonly expires: string | null;
12
+ }
13
+ /** Clock and retention bounds for one obtained source response. */
14
+ export interface SourceCacheInput {
15
+ readonly permission: SourceCachePermission | null;
16
+ readonly maximumCacheMs: number;
17
+ readonly readStartedAt: number;
18
+ readonly receivedAt: number;
19
+ readonly windowExpiresAt: number;
20
+ readonly headers: SourceCacheHeaders;
21
+ }
22
+ /** Fixed reasons safe to aggregate without content-bearing provider messages. */
23
+ export type SourceCacheSkipReason = 'not_permitted' | 'no_store' | 'revalidation_required' | 'invalid_cache_header' | 'invalid_bounds' | 'expired';
24
+ /** A finite allowed lifetime, or an explicit refusal to persist any source content. */
25
+ export type SourceCacheDecision = {
26
+ readonly kind: 'cache';
27
+ readonly expiresAt: number;
28
+ readonly evidenceId: string;
29
+ } | {
30
+ readonly kind: 'skip';
31
+ readonly reason: SourceCacheSkipReason;
32
+ };
33
+ /**
34
+ * Applies explicit permission and conservative provider/cache/window limits.
35
+ * Returned expiry is never extended by a history checkpoint or by calling this
36
+ * function again with the old response. A new read needs its own permission check.
37
+ */
38
+ export declare function decideSourceCache(input: SourceCacheInput): SourceCacheDecision;
39
+ //# sourceMappingURL=cachePolicy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cachePolicy.d.ts","sourceRoot":"","sources":["../src/cachePolicy.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,wFAAwF;AACxF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,mEAAmE;AACnE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAClD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;CACtC;AAED,iFAAiF;AACjF,MAAM,MAAM,qBAAqB,GAC7B,eAAe,GAAG,UAAU,GAAG,uBAAuB,GACtD,sBAAsB,GAAG,gBAAgB,GAAG,SAAS,CAAC;AAE1D,uFAAuF;AACvF,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACnF;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAA;CAAE,CAAC;AAiCtE;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,mBAAmB,CAiD9E"}
@@ -0,0 +1,97 @@
1
+ const integer = (value) => Number.isSafeInteger(value) && value >= 0;
2
+ const positive = (value) => integer(value) && value > 0;
3
+ const skip = (reason) => ({ kind: 'skip', reason });
4
+ /** Whole seconds written in digits only, as safe-integer milliseconds; anything else is null. */
5
+ function milliseconds(value) {
6
+ if (!/^\d+$/.test(value))
7
+ return null;
8
+ const converted = Number(value) * 1_000;
9
+ return integer(converted) ? converted : null;
10
+ }
11
+ /** An HTTP date accepted only in the exact form `toUTCString` writes, so a loose parse cannot invent a time. */
12
+ function date(value) {
13
+ if (value === null)
14
+ return null;
15
+ const parsed = Date.parse(value);
16
+ return integer(parsed) && new Date(parsed).toUTCString() === value ? parsed : null;
17
+ }
18
+ /** Cache-Control directives by lower-case name; a malformed or repeated directive answers null. */
19
+ function directives(value) {
20
+ const found = new Map();
21
+ if (value === null || value.trim() === '')
22
+ return found;
23
+ for (const part of value.split(',')) {
24
+ const match = /^([a-z][a-z0-9-]*)(?:\s*=\s*(?:"([^"]*)"|([^\s",]+)))?$/i.exec(part.trim());
25
+ const name = match?.[1]?.toLowerCase();
26
+ if (!match || !name || found.has(name))
27
+ return null;
28
+ found.set(name, match[2] ?? match[3] ?? null);
29
+ }
30
+ return found;
31
+ }
32
+ /**
33
+ * Applies explicit permission and conservative provider/cache/window limits.
34
+ * Returned expiry is never extended by a history checkpoint or by calling this
35
+ * function again with the old response. A new read needs its own permission check.
36
+ */
37
+ export function decideSourceCache(input) {
38
+ const permission = input.permission;
39
+ if (!permission || typeof permission.evidenceId !== 'string'
40
+ || permission.evidenceId.trim().length === 0 || !positive(permission.retentionMs)) {
41
+ return skip('not_permitted');
42
+ }
43
+ if (!positive(input.maximumCacheMs) || !integer(input.readStartedAt)
44
+ || !integer(input.receivedAt) || !integer(input.windowExpiresAt)
45
+ || input.receivedAt < input.readStartedAt)
46
+ return skip('invalid_bounds');
47
+ const policyEnd = input.readStartedAt + Math.min(permission.retentionMs, input.maximumCacheMs);
48
+ if (!integer(policyEnd))
49
+ return skip('invalid_bounds');
50
+ const rules = directives(input.headers.cacheControl);
51
+ if (rules === null)
52
+ return skip('invalid_cache_header');
53
+ if (rules.has('no-store'))
54
+ return skip('no_store');
55
+ if (rules.has('no-cache'))
56
+ return skip('revalidation_required');
57
+ const age = input.headers.age === null ? 0 : milliseconds(input.headers.age.trim());
58
+ const responseDate = date(input.headers.date);
59
+ const responseExpires = date(input.headers.expires);
60
+ if (age === null || (input.headers.date !== null && responseDate === null)
61
+ || (input.headers.expires !== null && responseExpires === null)) {
62
+ return skip('invalid_cache_header');
63
+ }
64
+ const elapsed = input.receivedAt - input.readStartedAt;
65
+ const apparentAge = responseDate === null ? 0 : Math.max(0, input.receivedAt - responseDate);
66
+ const correctedAge = Math.max(apparentAge, age + elapsed);
67
+ if (!integer(correctedAge))
68
+ return skip('invalid_cache_header');
69
+ let expiresAt = Math.min(policyEnd - age, input.windowExpiresAt);
70
+ for (const name of ['max-age', 's-maxage']) {
71
+ if (!rules.has(name))
72
+ continue;
73
+ const value = rules.get(name);
74
+ if (value === null || value === undefined)
75
+ return skip('invalid_cache_header');
76
+ const freshFor = milliseconds(value);
77
+ if (freshFor === null)
78
+ return skip('invalid_cache_header');
79
+ const freshUntil = input.receivedAt + freshFor - correctedAge;
80
+ if (!Number.isSafeInteger(freshUntil))
81
+ return skip('invalid_cache_header');
82
+ expiresAt = Math.min(expiresAt, freshUntil);
83
+ }
84
+ if (responseExpires !== null) {
85
+ const freshFor = responseExpires - (responseDate ?? input.readStartedAt);
86
+ const freshUntil = input.receivedAt + freshFor - correctedAge;
87
+ if (!Number.isSafeInteger(freshUntil))
88
+ return skip('invalid_cache_header');
89
+ expiresAt = Math.min(expiresAt, freshUntil, responseExpires);
90
+ }
91
+ if (!Number.isSafeInteger(expiresAt))
92
+ return skip('invalid_bounds');
93
+ if (expiresAt <= input.receivedAt)
94
+ return skip('expired');
95
+ return { kind: 'cache', expiresAt, evidenceId: permission.evidenceId };
96
+ }
97
+ //# sourceMappingURL=cachePolicy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cachePolicy.js","sourceRoot":"","sources":["../src/cachePolicy.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -6,4 +6,6 @@ export * from './sourceRef.js';
6
6
  export * from './readCapped.js';
7
7
  /** The shared limiter and response-producing calls run under it. */
8
8
  export * from './limiter.js';
9
+ /** Explicit retention permission and conservative source-cache expiry. */
10
+ export * from './cachePolicy.js';
9
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,cAAc,YAAY,CAAC;AAC3B,yDAAyD;AACzD,cAAc,gBAAgB,CAAC;AAC/B,8DAA8D;AAC9D,cAAc,iBAAiB,CAAC;AAChC,oEAAoE;AACpE,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,cAAc,YAAY,CAAC;AAC3B,yDAAyD;AACzD,cAAc,gBAAgB,CAAC;AAC/B,8DAA8D;AAC9D,cAAc,iBAAiB,CAAC;AAChC,oEAAoE;AACpE,cAAc,cAAc,CAAC;AAC7B,0EAA0E;AAC1E,cAAc,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -6,4 +6,6 @@ export * from './sourceRef.js';
6
6
  export * from './readCapped.js';
7
7
  /** The shared limiter and response-producing calls run under it. */
8
8
  export * from './limiter.js';
9
+ /** Explicit retention permission and conservative source-cache expiry. */
10
+ export * from './cachePolicy.js';
9
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,cAAc,YAAY,CAAC;AAC3B,yDAAyD;AACzD,cAAc,gBAAgB,CAAC;AAC/B,8DAA8D;AAC9D,cAAc,iBAAiB,CAAC;AAChC,oEAAoE;AACpE,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,cAAc,YAAY,CAAC;AAC3B,yDAAyD;AACzD,cAAc,gBAAgB,CAAC;AAC/B,8DAA8D;AAC9D,cAAc,iBAAiB,CAAC;AAChC,oEAAoE;AACpE,cAAc,cAAc,CAAC;AAC7B,0EAA0E;AAC1E,cAAc,kBAAkB,CAAC"}
package/manifest.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://agentos.sh/schemas/extension-manifest-v1.json",
3
3
  "id": "com.framers.research.account-sources",
4
4
  "name": "Account Sources",
5
- "version": "0.1.0",
5
+ "version": "0.2.0",
6
6
  "description": "A person's own accounts as sources: connector interfaces, passage attribution, capped reads and a shared limiter",
7
7
  "author": {
8
8
  "name": "Frame",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@framers/agentos-ext-account-sources",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "A person's own accounts as sources: connector interfaces, passage attribution, capped reads and a shared limiter",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -47,10 +47,10 @@
47
47
  "@types/node": "^20.12.12",
48
48
  "@vitest/coverage-v8": "^3.2.7",
49
49
  "rimraf": "^5.0.7",
50
- "typedoc": "^0.25.13",
50
+ "typedoc": "^0.28.20",
51
51
  "typescript": "^5.4.5",
52
52
  "vitest": "^3.2.7",
53
- "@framers/agentos": "^0.13.40"
53
+ "@framers/agentos": "^0.13.89"
54
54
  },
55
55
  "homepage": "https://github.com/framerslab/agentos-extensions/tree/master/registry/curated/research/account-sources#readme",
56
56
  "bugs": {