@vellumai/credential-executor 0.6.5 → 0.7.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/Dockerfile +5 -5
- package/bun.lock +15 -7
- package/node_modules/@vellumai/credential-storage/src/__tests__/package-boundary.test.ts +32 -6
- package/node_modules/@vellumai/egress-proxy/src/__tests__/package-boundary.test.ts +32 -1
- package/node_modules/@vellumai/egress-proxy/src/types.ts +19 -0
- package/node_modules/@vellumai/{ces-contracts → service-contracts}/bun.lock +1 -1
- package/node_modules/@vellumai/{ces-contracts → service-contracts}/package.json +4 -2
- package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/__tests__/contracts.test.ts +5 -1
- package/node_modules/@vellumai/service-contracts/src/__tests__/package-boundary.test.ts +155 -0
- package/node_modules/@vellumai/service-contracts/src/credential-rpc.ts +23 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +25 -0
- package/node_modules/@vellumai/{ces-contracts/src/index.ts → service-contracts/src/transport.ts} +6 -28
- package/node_modules/@vellumai/service-contracts/src/trust-rules.ts +116 -0
- package/package.json +3 -3
- package/src/__tests__/bulk-set-credentials.test.ts +1 -1
- package/src/__tests__/command-executor.test.ts +2 -2
- package/src/__tests__/http-executor.test.ts +1 -1
- package/src/__tests__/local-materializers.test.ts +1 -1
- package/src/__tests__/managed-integration.test.ts +1 -1
- package/src/__tests__/managed-lazy-getters.test.ts +1 -1
- package/src/__tests__/managed-materializers.test.ts +1 -1
- package/src/__tests__/managed-rejection.test.ts +1 -1
- package/src/__tests__/transport.test.ts +1 -1
- package/src/audit/store.ts +2 -2
- package/src/commands/executor.ts +2 -2
- package/src/grants/rpc-handlers.ts +1 -1
- package/src/http/audit.ts +1 -1
- package/src/http/executor.ts +2 -2
- package/src/http/policy.ts +1 -1
- package/src/main.ts +1 -1
- package/src/managed-errors.ts +2 -2
- package/src/managed-lazy-getters.ts +4 -4
- package/src/managed-main.ts +3 -3
- package/src/materializers/local.ts +1 -1
- package/src/server.ts +2 -2
- package/src/subjects/local.ts +2 -2
- package/src/subjects/managed.ts +1 -1
- package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +0 -471
- package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +0 -436
- /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/__tests__/grants.test.ts +0 -0
- /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/error.ts +0 -0
- /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/grants.ts +0 -0
- /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/handles.ts +0 -0
- /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/rendering.ts +0 -0
- /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/rpc.ts +0 -0
- /package/node_modules/@vellumai/{ces-contracts → service-contracts}/tsconfig.json +0 -0
package/Dockerfile
CHANGED
|
@@ -14,7 +14,7 @@ RUN curl -fsSL https://bun.sh/install | bash -s "bun-v1.3.11"
|
|
|
14
14
|
ENV PATH="/root/.bun/bin:${PATH}"
|
|
15
15
|
|
|
16
16
|
# Copy shared packages first (needed for repo-local dependencies)
|
|
17
|
-
COPY packages/
|
|
17
|
+
COPY packages/service-contracts ./packages/service-contracts
|
|
18
18
|
COPY packages/credential-storage ./packages/credential-storage
|
|
19
19
|
COPY packages/egress-proxy ./packages/egress-proxy
|
|
20
20
|
|
|
@@ -22,9 +22,6 @@ COPY packages/egress-proxy ./packages/egress-proxy
|
|
|
22
22
|
COPY credential-executor/package.json credential-executor/bun.lock* ./credential-executor/
|
|
23
23
|
RUN cd /app/credential-executor && bun install --frozen-lockfile
|
|
24
24
|
|
|
25
|
-
# Copy credential-executor source
|
|
26
|
-
COPY credential-executor ./credential-executor
|
|
27
|
-
|
|
28
25
|
# Runtime stage
|
|
29
26
|
FROM debian:trixie-slim@sha256:1d3c811171a08a5adaa4a163fbafd96b61b87aa871bbc7aa15431ac275d3d430 AS runner
|
|
30
27
|
|
|
@@ -42,9 +39,12 @@ RUN ln -sf /usr/local/bin/bun /usr/local/bin/bunx
|
|
|
42
39
|
RUN groupadd --system --gid 1001 ces && \
|
|
43
40
|
useradd --system --uid 1001 --gid ces --create-home ces
|
|
44
41
|
|
|
45
|
-
# Copy
|
|
42
|
+
# Copy installed deps + shared packages from builder.
|
|
46
43
|
COPY --from=builder --chown=ces:ces /app /app
|
|
47
44
|
|
|
45
|
+
# Copy source separately to avoid invalidating builder layer.
|
|
46
|
+
COPY --chown=ces:ces credential-executor ./
|
|
47
|
+
|
|
48
48
|
# Pre-create /ces-data so the non-root ces user can write to it
|
|
49
49
|
# when no PVC volume is mounted (e.g., direct docker run)
|
|
50
50
|
RUN mkdir -p /ces-data && chown ces:ces /ces-data
|
package/bun.lock
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
"": {
|
|
6
6
|
"name": "@vellumai/credential-executor",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@vellumai/ces-contracts": "file:../packages/ces-contracts",
|
|
9
8
|
"@vellumai/credential-storage": "file:../packages/credential-storage",
|
|
10
9
|
"@vellumai/egress-proxy": "file:../packages/egress-proxy",
|
|
10
|
+
"@vellumai/service-contracts": "file:../packages/service-contracts",
|
|
11
11
|
"pino": "9.14.0",
|
|
12
12
|
"pino-pretty": "13.1.3",
|
|
13
13
|
},
|
|
@@ -22,13 +22,15 @@
|
|
|
22
22
|
|
|
23
23
|
"@types/bun": ["@types/bun@1.3.10", "", { "dependencies": { "bun-types": "1.3.10" } }, "sha512-0+rlrUrOrTSskibryHbvQkDOWRJwJZqZlxrUs1u4oOoTln8+WIXBPmAuCF35SWB2z4Zl3E84Nl/D0P7803nigQ=="],
|
|
24
24
|
|
|
25
|
-
"@types/node": ["@types/node@25.
|
|
25
|
+
"@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
|
|
26
26
|
|
|
27
|
-
"@
|
|
27
|
+
"@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="],
|
|
28
28
|
|
|
29
|
-
"@vellumai/credential-storage": ["@vellumai/credential-storage@file:../packages/credential-storage", { "devDependencies": { "@types/bun": "
|
|
29
|
+
"@vellumai/credential-storage": ["@vellumai/credential-storage@file:../packages/credential-storage", { "devDependencies": { "@types/bun": "1.3.10", "typescript": "5.9.3" } }],
|
|
30
30
|
|
|
31
|
-
"@vellumai/egress-proxy": ["@vellumai/egress-proxy@file:../packages/egress-proxy", { "devDependencies": { "@types/bun": "
|
|
31
|
+
"@vellumai/egress-proxy": ["@vellumai/egress-proxy@file:../packages/egress-proxy", { "devDependencies": { "@types/bun": "1.3.10", "typescript": "5.9.3" } }],
|
|
32
|
+
|
|
33
|
+
"@vellumai/service-contracts": ["@vellumai/service-contracts@file:../packages/service-contracts", { "dependencies": { "zod": "4.3.6" }, "devDependencies": { "@types/bun": "1.2.4", "typescript": "5.7.3" } }],
|
|
32
34
|
|
|
33
35
|
"atomic-sleep": ["atomic-sleep@1.0.0", "", {}, "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="],
|
|
34
36
|
|
|
@@ -40,7 +42,7 @@
|
|
|
40
42
|
|
|
41
43
|
"end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="],
|
|
42
44
|
|
|
43
|
-
"fast-copy": ["fast-copy@4.0.
|
|
45
|
+
"fast-copy": ["fast-copy@4.0.3", "", {}, "sha512-58apWr0GUiDFM8+3afrO6eYwJBn9ZAhDOzG3L+/9llab/haCARS2UIfffmOurYLwbgDRs8n0rfr6qAAPEAuAQw=="],
|
|
44
46
|
|
|
45
47
|
"fast-safe-stringify": ["fast-safe-stringify@2.1.1", "", {}, "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="],
|
|
46
48
|
|
|
@@ -84,12 +86,18 @@
|
|
|
84
86
|
|
|
85
87
|
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
86
88
|
|
|
87
|
-
"undici-types": ["undici-types@7.
|
|
89
|
+
"undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="],
|
|
88
90
|
|
|
89
91
|
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
|
|
90
92
|
|
|
91
93
|
"zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
|
|
92
94
|
|
|
95
|
+
"@vellumai/service-contracts/@types/bun": ["@types/bun@1.2.4", "", { "dependencies": { "bun-types": "1.2.4" } }, "sha512-QtuV5OMR8/rdKJs213iwXDpfVvnskPXY/S0ZiFbsTjQZycuqPbMW8Gf/XhLfwE5njW8sxI2WjISURXPlHypMFA=="],
|
|
96
|
+
|
|
97
|
+
"@vellumai/service-contracts/typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="],
|
|
98
|
+
|
|
93
99
|
"pino-pretty/pino-abstract-transport": ["pino-abstract-transport@3.0.0", "", { "dependencies": { "split2": "^4.0.0" } }, "sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg=="],
|
|
100
|
+
|
|
101
|
+
"@vellumai/service-contracts/@types/bun/bun-types": ["bun-types@1.2.4", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-nDPymR207ZZEoWD4AavvEaa/KZe/qlrbMSchqpQwovPZCKc7pwMoENjEtHgMKaAjJhy+x6vfqSBA1QU3bJgs0Q=="],
|
|
94
102
|
}
|
|
95
103
|
}
|
|
@@ -3,8 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Ensures the package:
|
|
5
5
|
* 1. Does NOT import from the assistant daemon or CES modules.
|
|
6
|
-
* 2.
|
|
7
|
-
*
|
|
6
|
+
* 2. Does NOT import from x-client packages (@vellumai/assistant-client,
|
|
7
|
+
* @vellumai/ces-client, @vellumai/gateway-client).
|
|
8
|
+
* 3. Does NOT import from @vellumai/service-contracts runtime/internal modules
|
|
9
|
+
* (the aggregate root or any subpath beyond what credential-storage needs
|
|
10
|
+
* for pure type definitions is not required at all).
|
|
11
|
+
* 4. Exposes only local storage/runtime abstractions.
|
|
12
|
+
* 5. Remains portable and self-contained.
|
|
8
13
|
*/
|
|
9
14
|
|
|
10
15
|
import { describe, expect, test } from "bun:test";
|
|
@@ -59,6 +64,21 @@ const FORBIDDEN_IMPORT_PATTERNS = [
|
|
|
59
64
|
/from\s+["'].*\/tools\//,
|
|
60
65
|
/from\s+["'].*\/oauth\/oauth-store/,
|
|
61
66
|
/from\s+["'].*\/security\/secure-keys/,
|
|
67
|
+
|
|
68
|
+
// x-client packages (must not depend on any typed service client)
|
|
69
|
+
/from\s+["']@vellumai\/assistant-client(?:\/|["'])/,
|
|
70
|
+
/require\s*\(\s*["']@vellumai\/assistant-client(?:\/|["'])/,
|
|
71
|
+
/from\s+["']@vellumai\/ces-client(?:\/|["'])/,
|
|
72
|
+
/require\s*\(\s*["']@vellumai\/ces-client(?:\/|["'])/,
|
|
73
|
+
/from\s+["']@vellumai\/gateway-client(?:\/|["'])/,
|
|
74
|
+
/require\s*\(\s*["']@vellumai\/gateway-client(?:\/|["'])/,
|
|
75
|
+
|
|
76
|
+
// service-contracts aggregate root or internal subpaths
|
|
77
|
+
// credential-storage is a lower-layer package and must not depend on
|
|
78
|
+
// service-contracts (which sits at the same layer but deals with RPC
|
|
79
|
+
// protocol types, not storage abstractions).
|
|
80
|
+
/from\s+["']@vellumai\/service-contracts(?:\/|["'])/,
|
|
81
|
+
/require\s*\(\s*["']@vellumai\/service-contracts(?:\/|["'])/,
|
|
62
82
|
];
|
|
63
83
|
|
|
64
84
|
describe("package boundary", () => {
|
|
@@ -68,7 +88,7 @@ describe("package boundary", () => {
|
|
|
68
88
|
expect(sourceFiles.length).toBeGreaterThan(0);
|
|
69
89
|
});
|
|
70
90
|
|
|
71
|
-
test("does not import from assistant or
|
|
91
|
+
test("does not import from assistant, CES, x-client, or service-contracts modules", () => {
|
|
72
92
|
const violations: string[] = [];
|
|
73
93
|
|
|
74
94
|
for (const file of sourceFiles) {
|
|
@@ -101,7 +121,7 @@ describe("package boundary", () => {
|
|
|
101
121
|
expect(pkg.private).toBe(true);
|
|
102
122
|
});
|
|
103
123
|
|
|
104
|
-
test("package.json does not depend on assistant or
|
|
124
|
+
test("package.json does not depend on assistant, CES, x-client, or service-contracts packages", () => {
|
|
105
125
|
const pkg = JSON.parse(
|
|
106
126
|
readFileSync(join(PACKAGE_ROOT, "package.json"), "utf-8"),
|
|
107
127
|
);
|
|
@@ -113,8 +133,14 @@ describe("package boundary", () => {
|
|
|
113
133
|
const forbidden = Object.keys(allDeps).filter(
|
|
114
134
|
(dep) =>
|
|
115
135
|
dep.includes("assistant") ||
|
|
116
|
-
dep.includes("
|
|
117
|
-
|
|
136
|
+
dep.includes("daemon") ||
|
|
137
|
+
[
|
|
138
|
+
"@vellumai/ces-client",
|
|
139
|
+
"@vellumai/ces-contracts",
|
|
140
|
+
"@vellumai/service-contracts",
|
|
141
|
+
"@vellumai/assistant-client",
|
|
142
|
+
"@vellumai/gateway-client",
|
|
143
|
+
].includes(dep),
|
|
118
144
|
);
|
|
119
145
|
expect(forbidden).toEqual([]);
|
|
120
146
|
});
|
|
@@ -4,6 +4,13 @@
|
|
|
4
4
|
* These tests ensure the egress-proxy package remains isolated from
|
|
5
5
|
* assistant runtime and CES server implementation modules. If a direct
|
|
6
6
|
* import of those modules is introduced, these tests will fail.
|
|
7
|
+
*
|
|
8
|
+
* Tightened boundaries (added):
|
|
9
|
+
* - Does NOT import from x-client packages (@vellumai/assistant-client,
|
|
10
|
+
* @vellumai/ces-client, @vellumai/gateway-client).
|
|
11
|
+
* - Does NOT import from @vellumai/service-contracts (the egress-proxy
|
|
12
|
+
* package deals only with proxy session lifecycle and must not depend on
|
|
13
|
+
* CES wire-protocol types).
|
|
7
14
|
*/
|
|
8
15
|
|
|
9
16
|
import { describe, expect, test } from "bun:test";
|
|
@@ -66,6 +73,25 @@ const FORBIDDEN_PATTERNS = [
|
|
|
66
73
|
/require\s*\(.*\/gateway\/src\//,
|
|
67
74
|
/import\s+['"].*\/gateway\/src\//,
|
|
68
75
|
/import\s+['"]@vellumai\/vellum-gateway/,
|
|
76
|
+
|
|
77
|
+
// x-client packages (must not depend on any typed service client)
|
|
78
|
+
/from\s+['"]@vellumai\/assistant-client(?:\/|['"])/,
|
|
79
|
+
/import\s+['"]@vellumai\/assistant-client(?:\/|['"])/,
|
|
80
|
+
/require\s*\(['"]@vellumai\/assistant-client(?:\/|['"])/,
|
|
81
|
+
/from\s+['"]@vellumai\/ces-client(?:\/|['"])/,
|
|
82
|
+
/import\s+['"]@vellumai\/ces-client(?:\/|['"])/,
|
|
83
|
+
/require\s*\(['"]@vellumai\/ces-client(?:\/|['"])/,
|
|
84
|
+
/from\s+['"]@vellumai\/gateway-client(?:\/|['"])/,
|
|
85
|
+
/import\s+['"]@vellumai\/gateway-client(?:\/|['"])/,
|
|
86
|
+
/require\s*\(['"]@vellumai\/gateway-client(?:\/|['"])/,
|
|
87
|
+
|
|
88
|
+
// service-contracts (RPC protocol types — egress-proxy must not depend on CES wire types)
|
|
89
|
+
/from\s+['"]@vellumai\/service-contracts(?:\/|['"])/,
|
|
90
|
+
/import\s+['"]@vellumai\/service-contracts(?:\/|['"])/,
|
|
91
|
+
/require\s*\(['"]@vellumai\/service-contracts(?:\/|['"])/,
|
|
92
|
+
/from\s+['"]@vellumai\/ces-contracts(?:\/|['"])/,
|
|
93
|
+
/import\s+['"]@vellumai\/ces-contracts(?:\/|['"])/,
|
|
94
|
+
/require\s*\(['"]@vellumai\/ces-contracts(?:\/|['"])/,
|
|
69
95
|
];
|
|
70
96
|
|
|
71
97
|
describe("package boundary", () => {
|
|
@@ -94,7 +120,7 @@ describe("package boundary", () => {
|
|
|
94
120
|
}
|
|
95
121
|
});
|
|
96
122
|
|
|
97
|
-
test("package.json has no dependencies on assistant, CES, or
|
|
123
|
+
test("package.json has no dependencies on assistant, CES, gateway, x-client, or service-contracts", async () => {
|
|
98
124
|
const pkgJsonPath = resolve(PKG_SRC, "..", "package.json");
|
|
99
125
|
const pkgJson = JSON.parse(await Bun.file(pkgJsonPath).text());
|
|
100
126
|
|
|
@@ -109,6 +135,11 @@ describe("package boundary", () => {
|
|
|
109
135
|
"@vellumai/assistant",
|
|
110
136
|
"@vellumai/ces",
|
|
111
137
|
"@vellumai/vellum-gateway",
|
|
138
|
+
"@vellumai/assistant-client",
|
|
139
|
+
"@vellumai/ces-client",
|
|
140
|
+
"@vellumai/ces-contracts",
|
|
141
|
+
"@vellumai/gateway-client",
|
|
142
|
+
"@vellumai/service-contracts",
|
|
112
143
|
];
|
|
113
144
|
|
|
114
145
|
for (const dep of forbidden) {
|
|
@@ -197,12 +197,19 @@ export type PolicyDecision =
|
|
|
197
197
|
/**
|
|
198
198
|
* Callback invoked by the proxy HTTP forwarder for each outbound request.
|
|
199
199
|
* Returns injected headers on allow, or `null` to block the request.
|
|
200
|
+
*
|
|
201
|
+
* `method` and `requestHeaders` are populated for plain-HTTP proxied
|
|
202
|
+
* requests (absolute-URL form). For HTTPS CONNECT tunnels the proxy has
|
|
203
|
+
* not yet terminated TLS and cannot see HTTP-level details, so these are
|
|
204
|
+
* left undefined.
|
|
200
205
|
*/
|
|
201
206
|
export type PolicyCallback = (
|
|
202
207
|
hostname: string,
|
|
203
208
|
port: number | null,
|
|
204
209
|
path: string,
|
|
205
210
|
scheme: "http" | "https",
|
|
211
|
+
method?: string,
|
|
212
|
+
requestHeaders?: Record<string, string | string[] | undefined>,
|
|
206
213
|
) => Promise<Record<string, string> | null>;
|
|
207
214
|
|
|
208
215
|
/**
|
|
@@ -216,6 +223,18 @@ export interface ProxyApprovalRequest {
|
|
|
216
223
|
| PolicyDecisionAskUnauthenticated;
|
|
217
224
|
/** The proxy session ID that originated the request. */
|
|
218
225
|
sessionId: ProxySessionId;
|
|
226
|
+
/**
|
|
227
|
+
* HTTP method of the incoming request, when available. Undefined for HTTPS
|
|
228
|
+
* CONNECT tunnels — at CONNECT time the proxy has not terminated TLS so
|
|
229
|
+
* no HTTP-level information is visible.
|
|
230
|
+
*/
|
|
231
|
+
method?: string;
|
|
232
|
+
/**
|
|
233
|
+
* Curated subset of request headers, when available. Only non-sensitive
|
|
234
|
+
* headers are surfaced (content-type, content-length, user-agent, accept).
|
|
235
|
+
* Undefined for HTTPS CONNECT tunnels.
|
|
236
|
+
*/
|
|
237
|
+
requestHeaders?: Record<string, string>;
|
|
219
238
|
}
|
|
220
239
|
|
|
221
240
|
/**
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "@vellumai/
|
|
2
|
+
"name": "@vellumai/service-contracts",
|
|
3
3
|
"version": "0.0.1",
|
|
4
4
|
"private": true,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": "./src/index.ts",
|
|
9
|
+
"./credential-rpc": "./src/credential-rpc.ts",
|
|
10
|
+
"./trust-rules": "./src/trust-rules.ts",
|
|
9
11
|
"./handles": "./src/handles.ts",
|
|
10
12
|
"./grants": "./src/grants.ts",
|
|
11
13
|
"./rpc": "./src/rpc.ts",
|
|
12
14
|
"./rendering": "./src/rendering.ts",
|
|
13
|
-
"./
|
|
15
|
+
"./error": "./src/error.ts"
|
|
14
16
|
},
|
|
15
17
|
"scripts": {
|
|
16
18
|
"typecheck": "bunx tsc --noEmit",
|
package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/__tests__/contracts.test.ts
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Tests for @vellumai/
|
|
2
|
+
* Tests for @vellumai/service-contracts
|
|
3
3
|
*
|
|
4
4
|
* These tests verify:
|
|
5
5
|
* 1. The package can be consumed independently (no assistant/ or CES imports).
|
|
@@ -30,6 +30,10 @@ describe("package independence", () => {
|
|
|
30
30
|
"../grants.ts",
|
|
31
31
|
"../rpc.ts",
|
|
32
32
|
"../rendering.ts",
|
|
33
|
+
"../transport.ts",
|
|
34
|
+
"../credential-rpc.ts",
|
|
35
|
+
"../trust-rules.ts",
|
|
36
|
+
"../error.ts",
|
|
33
37
|
];
|
|
34
38
|
|
|
35
39
|
for (const file of sourceFiles) {
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package boundary tests for @vellumai/service-contracts.
|
|
3
|
+
*
|
|
4
|
+
* Ensures the package:
|
|
5
|
+
* 1. Does NOT import from assistant, gateway, credential-executor, or other
|
|
6
|
+
* service runtime modules.
|
|
7
|
+
* 2. Does NOT import from runtime shared packages that sit above it in the
|
|
8
|
+
* dependency hierarchy (@vellumai/credential-storage, @vellumai/egress-proxy,
|
|
9
|
+
* @vellumai/skill-host-contracts).
|
|
10
|
+
* 3. Does NOT import from x-client packages (@vellumai/assistant-client,
|
|
11
|
+
* @vellumai/ces-client, @vellumai/gateway-client).
|
|
12
|
+
* 4. Remains a pure schema/type package — no runtime dependencies beyond zod.
|
|
13
|
+
*
|
|
14
|
+
* @vellumai/service-contracts is the lowest layer of the shared packages
|
|
15
|
+
* hierarchy and must not depend on any higher-layer package.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { describe, expect, test } from "bun:test";
|
|
19
|
+
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
20
|
+
import { join, resolve } from "node:path";
|
|
21
|
+
|
|
22
|
+
const PACKAGE_ROOT = resolve(import.meta.dirname, "../..");
|
|
23
|
+
const SRC_DIR = join(PACKAGE_ROOT, "src");
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Recursively collect all .ts source files, excluding test and declaration files.
|
|
27
|
+
*/
|
|
28
|
+
function collectSourceFiles(dir: string): string[] {
|
|
29
|
+
const files: string[] = [];
|
|
30
|
+
for (const entry of readdirSync(dir)) {
|
|
31
|
+
const full = join(dir, entry);
|
|
32
|
+
const stat = statSync(full);
|
|
33
|
+
if (stat.isDirectory()) {
|
|
34
|
+
if (entry === "node_modules" || entry === "__tests__") continue;
|
|
35
|
+
files.push(...collectSourceFiles(full));
|
|
36
|
+
} else if (
|
|
37
|
+
entry.endsWith(".ts") &&
|
|
38
|
+
!entry.endsWith(".test.ts") &&
|
|
39
|
+
!entry.endsWith(".d.ts")
|
|
40
|
+
) {
|
|
41
|
+
files.push(full);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return files;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Patterns that must NOT appear in any import/require statement within
|
|
49
|
+
* source files. These catch imports from higher-layer packages that would
|
|
50
|
+
* create a forbidden upward dependency.
|
|
51
|
+
*/
|
|
52
|
+
const FORBIDDEN_IMPORT_PATTERNS = [
|
|
53
|
+
// Assistant runtime
|
|
54
|
+
/from\s+["'](?:\.\.\/)*assistant(?:\/|["'])/,
|
|
55
|
+
/require\s*\(\s*["'](?:\.\.\/)*assistant(?:\/|["'])/,
|
|
56
|
+
/from\s+["']@vellumai\/assistant(?:\/|["'])/,
|
|
57
|
+
/require\s*\(\s*["']@vellumai\/assistant(?:\/|["'])/,
|
|
58
|
+
|
|
59
|
+
// Gateway
|
|
60
|
+
/from\s+["'](?:\.\.\/)*gateway(?:\/|["'])/,
|
|
61
|
+
/require\s*\(\s*["'](?:\.\.\/)*gateway(?:\/|["'])/,
|
|
62
|
+
/from\s+["']@vellumai\/(?:vellum-)?gateway(?:\/|["'])/,
|
|
63
|
+
/require\s*\(\s*["']@vellumai\/(?:vellum-)?gateway(?:\/|["'])/,
|
|
64
|
+
|
|
65
|
+
// Credential executor
|
|
66
|
+
/from\s+["'](?:\.\.\/)*credential-executor(?:\/|["'])/,
|
|
67
|
+
/require\s*\(\s*["'](?:\.\.\/)*credential-executor(?:\/|["'])/,
|
|
68
|
+
/from\s+["']@vellumai\/credential-executor(?:\/|["'])/,
|
|
69
|
+
/require\s*\(\s*["']@vellumai\/credential-executor(?:\/|["'])/,
|
|
70
|
+
|
|
71
|
+
// Runtime shared packages (higher layer)
|
|
72
|
+
/from\s+["']@vellumai\/credential-storage(?:\/|["'])/,
|
|
73
|
+
/require\s*\(\s*["']@vellumai\/credential-storage(?:\/|["'])/,
|
|
74
|
+
/from\s+["']@vellumai\/egress-proxy(?:\/|["'])/,
|
|
75
|
+
/require\s*\(\s*["']@vellumai\/egress-proxy(?:\/|["'])/,
|
|
76
|
+
/from\s+["']@vellumai\/skill-host-contracts(?:\/|["'])/,
|
|
77
|
+
/require\s*\(\s*["']@vellumai\/skill-host-contracts(?:\/|["'])/,
|
|
78
|
+
|
|
79
|
+
// x-client packages (higher layer)
|
|
80
|
+
/from\s+["']@vellumai\/assistant-client(?:\/|["'])/,
|
|
81
|
+
/require\s*\(\s*["']@vellumai\/assistant-client(?:\/|["'])/,
|
|
82
|
+
/from\s+["']@vellumai\/ces-client(?:\/|["'])/,
|
|
83
|
+
/require\s*\(\s*["']@vellumai\/ces-client(?:\/|["'])/,
|
|
84
|
+
/from\s+["']@vellumai\/gateway-client(?:\/|["'])/,
|
|
85
|
+
/require\s*\(\s*["']@vellumai\/gateway-client(?:\/|["'])/,
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
describe("package boundary", () => {
|
|
89
|
+
const sourceFiles = collectSourceFiles(SRC_DIR);
|
|
90
|
+
|
|
91
|
+
test("has source files to validate", () => {
|
|
92
|
+
expect(sourceFiles.length).toBeGreaterThan(0);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test("does not import from runtime or higher-layer packages", () => {
|
|
96
|
+
const violations: string[] = [];
|
|
97
|
+
|
|
98
|
+
for (const file of sourceFiles) {
|
|
99
|
+
const content = readFileSync(file, "utf-8");
|
|
100
|
+
const lines = content.split("\n");
|
|
101
|
+
|
|
102
|
+
for (let i = 0; i < lines.length; i++) {
|
|
103
|
+
const line = lines[i];
|
|
104
|
+
for (const pattern of FORBIDDEN_IMPORT_PATTERNS) {
|
|
105
|
+
if (pattern.test(line)) {
|
|
106
|
+
const relative = file.replace(PACKAGE_ROOT + "/", "");
|
|
107
|
+
violations.push(`${relative}:${i + 1}: ${line.trim()}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (violations.length > 0) {
|
|
114
|
+
throw new Error(
|
|
115
|
+
`Found ${violations.length} forbidden import(s) in service-contracts package:\n` +
|
|
116
|
+
violations.map((v) => ` - ${v}`).join("\n") +
|
|
117
|
+
"\n\n" +
|
|
118
|
+
"@vellumai/service-contracts is a pure schema/type package and must not\n" +
|
|
119
|
+
"import from runtime services or higher-layer packages.",
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("package.json declares it as private", () => {
|
|
125
|
+
const pkg = JSON.parse(
|
|
126
|
+
readFileSync(join(PACKAGE_ROOT, "package.json"), "utf-8"),
|
|
127
|
+
);
|
|
128
|
+
expect(pkg.private).toBe(true);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test("package.json does not depend on runtime or higher-layer packages", () => {
|
|
132
|
+
const pkg = JSON.parse(
|
|
133
|
+
readFileSync(join(PACKAGE_ROOT, "package.json"), "utf-8"),
|
|
134
|
+
);
|
|
135
|
+
const allDeps = {
|
|
136
|
+
...pkg.dependencies,
|
|
137
|
+
...pkg.devDependencies,
|
|
138
|
+
...pkg.peerDependencies,
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const forbidden = Object.keys(allDeps).filter((dep) =>
|
|
142
|
+
[
|
|
143
|
+
"@vellumai/assistant",
|
|
144
|
+
"@vellumai/credential-storage",
|
|
145
|
+
"@vellumai/egress-proxy",
|
|
146
|
+
"@vellumai/skill-host-contracts",
|
|
147
|
+
"@vellumai/assistant-client",
|
|
148
|
+
"@vellumai/ces-client",
|
|
149
|
+
"@vellumai/gateway-client",
|
|
150
|
+
].includes(dep),
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
expect(forbidden).toEqual([]);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vellumai/service-contracts/credential-rpc
|
|
3
|
+
*
|
|
4
|
+
* Domain entrypoint for the CES (Credential Execution Service) transport and
|
|
5
|
+
* RPC surface. Re-exports the transport/RPC/handles/grants/rendering/error
|
|
6
|
+
* contracts without the trust-rule helpers.
|
|
7
|
+
*
|
|
8
|
+
* Prefer this subpath over the root `.` import when you only need the
|
|
9
|
+
* credential RPC surface:
|
|
10
|
+
*
|
|
11
|
+
* import { CesRpcMethod, MakeAuthenticatedRequestSchema } from "@vellumai/service-contracts/credential-rpc";
|
|
12
|
+
*
|
|
13
|
+
* For trust-rule types use the dedicated subpath:
|
|
14
|
+
*
|
|
15
|
+
* import { TrustRule, parseTrustRule } from "@vellumai/service-contracts/trust-rules";
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export * from "./transport.js";
|
|
19
|
+
export * from "./error.js";
|
|
20
|
+
export * from "./handles.js";
|
|
21
|
+
export * from "./grants.js";
|
|
22
|
+
export * from "./rendering.js";
|
|
23
|
+
export * from "./rpc.js";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vellumai/service-contracts — aggregate export (compat entry point)
|
|
3
|
+
*
|
|
4
|
+
* This is a compatibility aggregate that re-exports everything from all
|
|
5
|
+
* submodules. Prefer the explicit domain subpaths for new code:
|
|
6
|
+
*
|
|
7
|
+
* - `@vellumai/service-contracts/credential-rpc` — transport, RPC, handles, grants, rendering, error
|
|
8
|
+
* - `@vellumai/service-contracts/trust-rules` — trust-rule types and parsing helpers
|
|
9
|
+
*
|
|
10
|
+
* Fine-grained subpaths are also available for low-friction migration:
|
|
11
|
+
* `./rpc`, `./handles`, `./grants`, `./rendering`, `./error`, `./trust-rules`
|
|
12
|
+
*
|
|
13
|
+
* Neutral wire-protocol contracts for communication between the assistant
|
|
14
|
+
* daemon and the Credential Execution Service (CES). This package is
|
|
15
|
+
* intentionally free of imports from `assistant/` or any CES implementation
|
|
16
|
+
* module so that both sides can depend on it without circular references.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export * from "./transport.js";
|
|
20
|
+
export * from "./error.js";
|
|
21
|
+
export * from "./handles.js";
|
|
22
|
+
export * from "./grants.js";
|
|
23
|
+
export * from "./rpc.js";
|
|
24
|
+
export * from "./rendering.js";
|
|
25
|
+
export * from "./trust-rules.js";
|
package/node_modules/@vellumai/{ces-contracts/src/index.ts → service-contracts/src/transport.ts}
RENAMED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Transport-level handshake and envelope schemas.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* module so that both sides can depend on it without circular references.
|
|
4
|
+
* Extracted from the aggregate index to allow credential-rpc.ts to import
|
|
5
|
+
* the full transport surface without creating a circular dependency through
|
|
6
|
+
* index.ts.
|
|
8
7
|
*/
|
|
9
8
|
|
|
10
9
|
import { z } from "zod";
|
|
@@ -35,9 +34,8 @@ export const HandshakeRequestSchema = z.object({
|
|
|
35
34
|
assistantApiKey: z.string().optional(),
|
|
36
35
|
/**
|
|
37
36
|
* Optional platform assistant ID passed from the assistant runtime.
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* so CES can use it for platform credential materialisation.
|
|
37
|
+
* The assistant ID is not available at CES startup (warm-pool pods),
|
|
38
|
+
* so the assistant forwards it here for platform credential materialisation.
|
|
41
39
|
*/
|
|
42
40
|
assistantId: z.string().optional(),
|
|
43
41
|
});
|
|
@@ -75,16 +73,6 @@ export const RpcEnvelopeSchema = z.object({
|
|
|
75
73
|
});
|
|
76
74
|
export type RpcEnvelope = z.infer<typeof RpcEnvelopeSchema>;
|
|
77
75
|
|
|
78
|
-
// ---------------------------------------------------------------------------
|
|
79
|
-
// RPC error (defined in error.ts to avoid circular deps with rpc.ts)
|
|
80
|
-
// ---------------------------------------------------------------------------
|
|
81
|
-
|
|
82
|
-
export {
|
|
83
|
-
RpcErrorSchema,
|
|
84
|
-
type RpcError,
|
|
85
|
-
MANAGED_LOCAL_STATIC_REJECTION_ERROR,
|
|
86
|
-
} from "./error.js";
|
|
87
|
-
|
|
88
76
|
// ---------------------------------------------------------------------------
|
|
89
77
|
// Tool request / response base shapes
|
|
90
78
|
// ---------------------------------------------------------------------------
|
|
@@ -143,13 +131,3 @@ export const TransportMessageSchema = z.discriminatedUnion("type", [
|
|
|
143
131
|
RpcEnvelopeSchema.extend({ type: z.literal("rpc") }),
|
|
144
132
|
]);
|
|
145
133
|
export type TransportMessage = z.infer<typeof TransportMessageSchema>;
|
|
146
|
-
|
|
147
|
-
// ---------------------------------------------------------------------------
|
|
148
|
-
// Re-exports from sub-modules
|
|
149
|
-
// ---------------------------------------------------------------------------
|
|
150
|
-
|
|
151
|
-
export * from "./handles.js";
|
|
152
|
-
export * from "./grants.js";
|
|
153
|
-
export * from "./rpc.js";
|
|
154
|
-
export * from "./rendering.js";
|
|
155
|
-
export * from "./trust-rules.js";
|