@cat-factory/server 0.239.1 → 0.240.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.
@@ -1 +1 @@
1
- {"version":3,"file":"openapiDocument.generated.js","sourceRoot":"","sources":["../../../src/modules/publicApi/openapiDocument.generated.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,EAAE;AACF,0FAA0F;AAC1F,8FAA8F;AAC9F,8FAA8F;AAC9F,8EAA8E;AAE9E,MAAM,CAAC,MAAM,YAAY,GAAG,w6sZAAw6sZ,CAAA"}
1
+ {"version":3,"file":"openapiDocument.generated.js","sourceRoot":"","sources":["../../../src/modules/publicApi/openapiDocument.generated.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,EAAE;AACF,0FAA0F;AAC1F,8FAA8F;AAC9F,8FAA8F;AAC9F,8EAA8E;AAE9E,MAAM,CAAC,MAAM,YAAY,GAAG,wluZAAwluZ,CAAA"}
@@ -0,0 +1,42 @@
1
+ import type { DeploymentDocumentResolver, DocumentContent, DocumentSourceKind } from '@cat-factory/kernel';
2
+ /**
3
+ * A {@link DeploymentDocumentResolver} backed by the mothership's
4
+ * `POST /internal/prompt-fragments/document-bodies`, presenting the node's machine token.
5
+ *
6
+ * **The credential never crosses; the BODY does.** The deployment's document credentials live in
7
+ * the mothership's environment, and `ENCRYPTION_KEY`-class configuration does not reach a laptop,
8
+ * so a node cannot authenticate to the vendor itself. That is the same rule that keeps a
9
+ * decrypting repository off the remote route, applied to a resolver instead of a repository.
10
+ *
11
+ * **A failed read THROWS; it never answers "no such document".** An unreachable mothership and a
12
+ * document this deployment cannot resolve are the same value and opposite facts, and the caller
13
+ * (`FragmentLibraryService.resolveDocumentBody`) degrades a THROW to the fragment's registered
14
+ * body with a warning naming the fragment. Answering silently-absent instead would produce the
15
+ * identical prompt with no warning anywhere, which is exactly the stale-standard failure that is
16
+ * indistinguishable from a current one.
17
+ */
18
+ export declare class HttpDeploymentDocumentResolver implements DeploymentDocumentResolver {
19
+ private readonly opts;
20
+ constructor(opts: {
21
+ baseUrl: string;
22
+ /** Fixed token, or a provider read PER REQUEST (the shape every other machine client takes). */
23
+ token: string | (() => string | null);
24
+ /**
25
+ * The sources the MOTHERSHIP has configured, as reported at connect time.
26
+ *
27
+ * A node cannot see the mothership's environment, so `configured()` would otherwise have to
28
+ * be a network call, and it is asked on a hot path (per document-backed entry, per catalog
29
+ * resolve) by a caller that only wants to know whether to bother. Absent ⇒ assume every
30
+ * deployment-scopable source may be served and let the read itself decide, which is the safe
31
+ * direction: it costs one round trip that returns nothing, where the opposite would silently
32
+ * skip a document the mothership could have served.
33
+ */
34
+ configuredSources?: readonly DocumentSourceKind[];
35
+ fetchImpl?: typeof fetch;
36
+ });
37
+ configured(source: DocumentSourceKind): boolean;
38
+ fetch(source: DocumentSourceKind, externalId: string): Promise<DocumentContent>;
39
+ probeVersion(source: DocumentSourceKind, externalId: string): Promise<string>;
40
+ private read;
41
+ }
42
+ //# sourceMappingURL=deploymentDocuments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploymentDocuments.d.ts","sourceRoot":"","sources":["../../src/persistence/deploymentDocuments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAC1B,eAAe,EACf,kBAAkB,EACnB,MAAM,qBAAqB,CAAA;AAU5B;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,8BAA+B,YAAW,0BAA0B;IAE7E,OAAO,CAAC,QAAQ,CAAC,IAAI;IADvB,YACmB,IAAI,EAAE;QACrB,OAAO,EAAE,MAAM,CAAA;QACf,gGAAgG;QAChG,KAAK,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,CAAA;QACrC;;;;;;;;;WASG;QACH,iBAAiB,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;QACjD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;KACzB,EACC;IAEJ,UAAU,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAG9C;IAEK,KAAK,CAAC,MAAM,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CASpF;IAEK,YAAY,CAAC,MAAM,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKlF;YAEa,IAAI;CA8DnB"}
@@ -0,0 +1,96 @@
1
+ import { UnavailableError, describeError } from '@cat-factory/kernel';
2
+ import { isDeploymentScopedSource } from '@cat-factory/contracts';
3
+ import { documentBodyRefKey } from '../modules/promptFragments/PromptFragmentsInternalController.js';
4
+ // The client half of the mothership-mode DEPLOYMENT-scoped document read (see
5
+ // `../modules/promptFragments/PromptFragmentsInternalController.ts` for why the body crosses the
6
+ // machine API rather than the credential). The sibling of `promptFragments.ts` and
7
+ // `foundationalBuiltins.ts`, written to the same contract for the same reason.
8
+ /**
9
+ * A {@link DeploymentDocumentResolver} backed by the mothership's
10
+ * `POST /internal/prompt-fragments/document-bodies`, presenting the node's machine token.
11
+ *
12
+ * **The credential never crosses; the BODY does.** The deployment's document credentials live in
13
+ * the mothership's environment, and `ENCRYPTION_KEY`-class configuration does not reach a laptop,
14
+ * so a node cannot authenticate to the vendor itself. That is the same rule that keeps a
15
+ * decrypting repository off the remote route, applied to a resolver instead of a repository.
16
+ *
17
+ * **A failed read THROWS; it never answers "no such document".** An unreachable mothership and a
18
+ * document this deployment cannot resolve are the same value and opposite facts, and the caller
19
+ * (`FragmentLibraryService.resolveDocumentBody`) degrades a THROW to the fragment's registered
20
+ * body with a warning naming the fragment. Answering silently-absent instead would produce the
21
+ * identical prompt with no warning anywhere, which is exactly the stale-standard failure that is
22
+ * indistinguishable from a current one.
23
+ */
24
+ export class HttpDeploymentDocumentResolver {
25
+ opts;
26
+ constructor(opts) {
27
+ this.opts = opts;
28
+ }
29
+ configured(source) {
30
+ if (!isDeploymentScopedSource(source))
31
+ return false;
32
+ return this.opts.configuredSources?.includes(source) ?? true;
33
+ }
34
+ async fetch(source, externalId) {
35
+ const content = await this.read(source, externalId);
36
+ return {
37
+ externalId,
38
+ title: '',
39
+ url: '',
40
+ body: content.body,
41
+ version: content.version,
42
+ };
43
+ }
44
+ async probeVersion(source, externalId) {
45
+ // The mothership's own resolver caches the body, so this is not the extra fetch it looks
46
+ // like: the node's `documentBodyCache` asks for a version only when its entry enters the
47
+ // refresh window, and the mothership answers from the copy it just verified.
48
+ return (await this.read(source, externalId)).version;
49
+ }
50
+ async read(source, externalId) {
51
+ const fetchImpl = this.opts.fetchImpl ?? fetch;
52
+ const token = typeof this.opts.token === 'function' ? this.opts.token() : this.opts.token;
53
+ const url = `${this.opts.baseUrl.replace(/\/$/, '')}/internal/prompt-fragments/document-bodies`;
54
+ let res;
55
+ try {
56
+ res = await fetchImpl(url, {
57
+ method: 'POST',
58
+ headers: {
59
+ authorization: `Bearer ${token ?? ''}`,
60
+ 'content-type': 'application/json',
61
+ },
62
+ body: JSON.stringify({ refs: [{ source, externalId }] }),
63
+ });
64
+ }
65
+ catch (error) {
66
+ throw new UnavailableError('A deployment-scoped document could not be read from the mothership', 'deployment_document_unreachable',
67
+ // Scrubbed through `redactSecrets`, because a fetch failure routinely echoes the request
68
+ // URL, which here carries the mothership's address.
69
+ describeError(error));
70
+ }
71
+ if (!res.ok) {
72
+ // Includes a mothership OLDER than this node, which answers 404 for a route it does not
73
+ // serve. Reading that as "the document is gone" would silently pin the registered body.
74
+ throw new UnavailableError('The mothership refused a deployment-scoped document read', 'deployment_document_unreachable', { status: res.status });
75
+ }
76
+ const payload = (await res.json().catch(() => null));
77
+ const bodies = payload?.bodies;
78
+ if (!bodies || typeof bodies !== 'object' || Array.isArray(bodies)) {
79
+ throw new UnavailableError('The mothership returned an unreadable deployment-document reply', 'deployment_document_unreachable', { field: 'bodies' });
80
+ }
81
+ // Indexed with the SERVER's own key function, never a locally re-spelled one: the pair
82
+ // `(source, externalId)` is what identifies a document, and a client that rebuilds that
83
+ // string itself is one rename away from silently indexing nothing.
84
+ const entry = bodies[documentBodyRefKey(source, externalId)];
85
+ const body = entry?.body;
86
+ const version = entry?.version;
87
+ if (typeof body !== 'string' || typeof version !== 'string') {
88
+ // ABSENT means the mothership could not resolve it either (it omits rather than failing the
89
+ // whole batch, and logs why on its own side). Throwing keeps the node's disposition the same
90
+ // as a standalone deployment's: degrade to the registered body AND say so.
91
+ throw new UnavailableError('The mothership could not resolve this deployment-scoped document', 'deployment_document_unresolved', { source });
92
+ }
93
+ return { body, version };
94
+ }
95
+ }
96
+ //# sourceMappingURL=deploymentDocuments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploymentDocuments.js","sourceRoot":"","sources":["../../src/persistence/deploymentDocuments.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/server",
3
- "version": "0.239.1",
3
+ "version": "0.240.0",
4
4
  "description": "Runtime-neutral HTTP layer for the Agent Architecture Board: the Hono controllers, middleware (auth/authz/CORS/error), request helpers and the gateway seams shared by every deployment facade (Cloudflare Worker, Node service).",
5
5
  "repository": {
6
6
  "type": "git",
@@ -31,13 +31,13 @@
31
31
  "jose": "^6.2.8",
32
32
  "pino": "^10.3.1",
33
33
  "valibot": "^1.4.2",
34
- "@cat-factory/agents": "0.116.7",
35
- "@cat-factory/integrations": "0.140.1",
36
- "@cat-factory/contracts": "0.261.0",
37
- "@cat-factory/mcp-server": "0.16.0",
38
- "@cat-factory/orchestration": "0.228.1",
39
- "@cat-factory/spend": "0.15.26",
40
- "@cat-factory/kernel": "0.260.0"
34
+ "@cat-factory/agents": "0.117.0",
35
+ "@cat-factory/integrations": "0.141.0",
36
+ "@cat-factory/kernel": "0.262.0",
37
+ "@cat-factory/contracts": "0.262.0",
38
+ "@cat-factory/mcp-server": "0.16.1",
39
+ "@cat-factory/orchestration": "0.230.0",
40
+ "@cat-factory/spend": "0.15.28"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "^26.1.2",