@axiom-lattice/pg-stores 5.2.1 → 5.2.3
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/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @axiom-lattice/pg-stores@5.2.
|
|
2
|
+
> @axiom-lattice/pg-stores@5.2.3 build /home/runner/work/agentic/agentic/packages/pg-stores
|
|
3
3
|
> tsup src/index.ts --format cjs,esm --dts --sourcemap
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
[34mESM[39m Build start
|
|
11
11
|
[32mCJS[39m [1mdist/index.js [22m[32m585.57 KB[39m
|
|
12
12
|
[32mCJS[39m [1mdist/index.js.map [22m[32m1.04 MB[39m
|
|
13
|
-
[32mCJS[39m ⚡️ Build success in
|
|
13
|
+
[32mCJS[39m ⚡️ Build success in 966ms
|
|
14
14
|
[32mESM[39m [1mdist/index.mjs [22m[32m574.26 KB[39m
|
|
15
15
|
[32mESM[39m [1mdist/index.mjs.map [22m[32m1.04 MB[39m
|
|
16
|
-
[32mESM[39m ⚡️ Build success in
|
|
16
|
+
[32mESM[39m ⚡️ Build success in 1003ms
|
|
17
17
|
[34mDTS[39m Build start
|
|
18
|
-
[32mDTS[39m ⚡️ Build success in
|
|
18
|
+
[32mDTS[39m ⚡️ Build success in 14653ms
|
|
19
19
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m123.99 KB[39m
|
|
20
20
|
[32mDTS[39m [1mdist/index.d.mts [22m[32m123.99 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,107 @@
|
|
|
1
1
|
# @axiom-lattice/pg-stores
|
|
2
2
|
|
|
3
|
+
## 5.2.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [ea7ede5]
|
|
8
|
+
- @axiom-lattice/core@13.0.1
|
|
9
|
+
- @axiom-lattice/protocols@7.5.0
|
|
10
|
+
|
|
11
|
+
## 5.2.2
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 9bbf5ce: ## Collection batch tools and Open MCP consolidation
|
|
16
|
+
|
|
17
|
+
BREAKING (core): the collection agent tool `add_entry` is replaced by
|
|
18
|
+
`add_entries` without a compatibility alias, so agent prompts, skills, and
|
|
19
|
+
saved tool allowlists that name `add_entry` must update. `add_entries` accepts
|
|
20
|
+
1-50 entries, performs one all-or-nothing vector-store call, and generates each
|
|
21
|
+
entry's `_id` and `_created_at`. Collection middleware, plugin metadata,
|
|
22
|
+
capability mapping, built-in guidance, and the React tool catalog are kept in
|
|
23
|
+
sync.
|
|
24
|
+
|
|
25
|
+
The collection delete agent tool `delete_entry` is also replaced by
|
|
26
|
+
`delete_entries` without a compatibility alias: it accepts 1-50 ids and performs
|
|
27
|
+
one idempotent `in` vector-store delete on pgvector/memory, with an exact-ID
|
|
28
|
+
fallback for unknown backends so an unsupported filter cannot wipe a collection.
|
|
29
|
+
`SimpleMemoryVectorStore` now supports `in`/`notIn` metadata filters. Deleting a
|
|
30
|
+
collection now also drops its vector store, and single-entry create/update keep
|
|
31
|
+
server-owned identity and attempt to restore the old entry if a rewrite fails.
|
|
32
|
+
|
|
33
|
+
Open MCP now exposes all ten collection tools under the sole `collection` domain
|
|
34
|
+
(`collection_<action>`) with readOnly/destructive annotations. The built-in
|
|
35
|
+
`kbProvider` / `kb_search` tool and `kb` domain are removed; browser/preview and
|
|
36
|
+
sandbox tokens now carry the read-only `collection.search_collection` grant
|
|
37
|
+
instead. Open credentials still need a collection grant to call the tools, and key
|
|
38
|
+
creation/update rejects empty-item collection grants so a destructive domain
|
|
39
|
+
cannot be granted wholesale by accident.
|
|
40
|
+
|
|
41
|
+
Additive surfaces: REST gains `POST /api/collections/:name/entries/batch` and
|
|
42
|
+
`DELETE /api/collections/:name/entries/batch`, and the client SDK gains
|
|
43
|
+
`client.collections.entries(name).createMany()` / `deleteMany()`, sharing the
|
|
44
|
+
same limit and all-or-nothing semantics. Existing single-entry endpoints,
|
|
45
|
+
`create()`, and `delete(id)` are unchanged.
|
|
46
|
+
|
|
47
|
+
## OIDC public clients
|
|
48
|
+
|
|
49
|
+
Make the OIDC client secret optional so public clients can use Authorization
|
|
50
|
+
Code + PKCE with `token_endpoint_auth_method=none`, matching the protocol
|
|
51
|
+
default. `OIDC_CLIENT_SECRET` may be omitted for the env provider, Platform
|
|
52
|
+
Admin's provider form no longer requires a secret on create, and the gateway,
|
|
53
|
+
client SDK, and Platform Ops provider tools accept a secret-less configuration.
|
|
54
|
+
Confidential clients continue to use the existing encrypted client-secret flow.
|
|
55
|
+
|
|
56
|
+
## Security dependency updates
|
|
57
|
+
|
|
58
|
+
Follow up the Wiz remediation with `pnpm audit`: bump the pinned transitive
|
|
59
|
+
dependencies to the advisories published after the scan (shell-quote 1.11 —
|
|
60
|
+
critical command injection — fastify 5.12.6, @fastify/busboy 3.2.2,
|
|
61
|
+
@hono/node-server 2.1.3, brace-expansion 1.1.21/2.1.7/5.0.12,
|
|
62
|
+
body-parser 1.20.9/2.4.0, decode-uri-component 0.5.1, fast-uri 3.1.9/4.2.3,
|
|
63
|
+
glob 10.5/11.1/14.0.4, langsmith 0.12, picomatch 2.3.2/4.0.4,
|
|
64
|
+
protobufjs 7.6.5/8.8.1, source-map-js 1.2.2, undici 7.30.1, sanitize-html
|
|
65
|
+
2.18.1, tar 7.5.22, tmp 0.2.7, vite 6.4.5, yaml 2.9.1, ajv 6.14/8.18,
|
|
66
|
+
mysql2 3.23.1, uuid 11.1, and others). Overrides are scoped per major line
|
|
67
|
+
where different majors are both required, and none pins below a declaring
|
|
68
|
+
package's range. Further zero-out pass: echarts 5.5 → 6.1 in react-sdk,
|
|
69
|
+
katex 0.19.1 (the patched range starts at 0.18.2), glob 14.0.4 for every
|
|
70
|
+
affected major line (10/11/13/14; glob 7 is outside the advisory range),
|
|
71
|
+
minimatch 11.0.8 for every vulnerable line, rimraf 4/5 → 6.1.4 (drops the
|
|
72
|
+
glob 9 dependency), ibm-cloud-sdk-core 5.9.4 (pulls file-type 21.3.4), and
|
|
73
|
+
fast-xml-parser 5.12.0. The client-sdk build moves from tsup 6.7 to 8.5,
|
|
74
|
+
clearing the last GHSA-3mv9-4h5g-vhg3 finding. Drop the unused `xlsx`
|
|
75
|
+
dependency from `apps/web`, which has no patched npm release.
|
|
76
|
+
|
|
77
|
+
Overrides only apply to this monorepo, so also raise the published packages'
|
|
78
|
+
own dependency ranges to patched versions, otherwise downstream consumers
|
|
79
|
+
(fina_demo) resolve the old lower bounds when they reinstall: fastify
|
|
80
|
+
^5.12.6 (gateway, microsandbox-service, opensandbox-gateway), react-router
|
|
81
|
+
^7.18.2, vite ^6.4.5, mysql2 ^3.23.1 (core), and uuid ^11.1.1 (core, gateway,
|
|
82
|
+
pg-stores, react-sdk, and the cli-a2a peer range).
|
|
83
|
+
|
|
84
|
+
## Reverse-proxy mount-prefix support
|
|
85
|
+
|
|
86
|
+
Support deploying the gateway behind a reverse-proxy path prefix (`/harness`
|
|
87
|
+
or any other mount point) without hardcoding it.
|
|
88
|
+
|
|
89
|
+
Gateway-rendered pages no longer emit root-absolute asset URLs: the embed chat
|
|
90
|
+
shell and MCP App share shell reference their bundles relative to the page, and
|
|
91
|
+
shared HTML gets a relative `<base href>` (plus a page-relative password-unlock
|
|
92
|
+
request). Client-side URL derivation now keeps the externally visible prefix
|
|
93
|
+
instead of reducing URLs to `location.origin`: the embed loader strips its known
|
|
94
|
+
`/embed/agent-chat-loader.js` suffix, the embed page recovers its base from
|
|
95
|
+
`<mount>/api/web-apps/:id/chat`, the MCP App share page keeps `<mount>/s/:token`,
|
|
96
|
+
and MCP App link resolution/sandbox loading use the gateway base derived from the
|
|
97
|
+
client `baseURL`. Root-path deployments resolve to the same absolute URLs as
|
|
98
|
+
before. Adds a deterministic `/harness` embed e2e (prefix-stripping proxy) and
|
|
99
|
+
random-prefix unit coverage.
|
|
100
|
+
|
|
101
|
+
- Updated dependencies [9bbf5ce]
|
|
102
|
+
- @axiom-lattice/core@13.0.0
|
|
103
|
+
- @axiom-lattice/protocols@7.4.0
|
|
104
|
+
|
|
3
105
|
## 5.2.1
|
|
4
106
|
|
|
5
107
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axiom-lattice/pg-stores",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.3",
|
|
4
4
|
"description": "PG stores implementation for Axiom Lattice framework",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"@langchain/core": "1.3.2",
|
|
26
26
|
"pg": "^8.16.3",
|
|
27
27
|
"uuid": "^11.1.1",
|
|
28
|
-
"@axiom-lattice/core": "
|
|
29
|
-
"@axiom-lattice/protocols": "7.
|
|
28
|
+
"@axiom-lattice/core": "13.0.1",
|
|
29
|
+
"@axiom-lattice/protocols": "7.5.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/jest": "^29.5.14",
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { Pool } from "pg";
|
|
3
|
+
import { PGVectorStore } from "@langchain/community/vectorstores/pgvector";
|
|
4
|
+
import { Embeddings } from "@langchain/core/embeddings";
|
|
5
|
+
import { Document } from "@langchain/core/documents";
|
|
6
|
+
|
|
7
|
+
const databaseUrl = process.env.TEST_DATABASE_URL;
|
|
8
|
+
const describeIfDatabase = databaseUrl ? describe : describe.skip;
|
|
9
|
+
|
|
10
|
+
class FakeEmbeddings extends Embeddings {
|
|
11
|
+
constructor() {
|
|
12
|
+
super({});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async embedDocuments(texts: string[]): Promise<number[][]> {
|
|
16
|
+
return texts.map(() => [0.1, 0.2, 0.3]);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async embedQuery(): Promise<number[]> {
|
|
20
|
+
return [0.1, 0.2, 0.3];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describeIfDatabase("PGVectorStore collection delete filter", () => {
|
|
25
|
+
const tableName = `collection_delete_${randomUUID().replace(/-/g, "")}`;
|
|
26
|
+
let store: PGVectorStore | undefined;
|
|
27
|
+
let pool: Pool;
|
|
28
|
+
let available = false;
|
|
29
|
+
|
|
30
|
+
beforeAll(async () => {
|
|
31
|
+
pool = new Pool({ connectionString: databaseUrl });
|
|
32
|
+
try {
|
|
33
|
+
await pool.query("CREATE EXTENSION IF NOT EXISTS vector");
|
|
34
|
+
store = await PGVectorStore.initialize(new FakeEmbeddings(), {
|
|
35
|
+
postgresConnectionOptions: { connectionString: databaseUrl },
|
|
36
|
+
tableName,
|
|
37
|
+
columns: {
|
|
38
|
+
idColumnName: "id",
|
|
39
|
+
vectorColumnName: "vector",
|
|
40
|
+
contentColumnName: "content",
|
|
41
|
+
metadataColumnName: "metadata",
|
|
42
|
+
},
|
|
43
|
+
distanceStrategy: "cosine" as never,
|
|
44
|
+
});
|
|
45
|
+
available = true;
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.warn(
|
|
48
|
+
"PGVectorStore delete filter integration test skipped: pgvector is unavailable",
|
|
49
|
+
error instanceof Error ? error.message : String(error),
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
beforeEach(async () => {
|
|
55
|
+
if (!available || !store) return;
|
|
56
|
+
await store.delete({ filter: { marker: "seed" } });
|
|
57
|
+
await store.addDocuments([
|
|
58
|
+
new Document({ pageContent: "one", metadata: { _id: "1", marker: "seed" } }),
|
|
59
|
+
new Document({ pageContent: "two", metadata: { _id: "2", marker: "seed" } }),
|
|
60
|
+
new Document({ pageContent: "three", metadata: { _id: "3", marker: "seed" } }),
|
|
61
|
+
]);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
afterAll(async () => {
|
|
65
|
+
if (available) {
|
|
66
|
+
await pool.query(`DROP TABLE IF EXISTS "${tableName}"`);
|
|
67
|
+
}
|
|
68
|
+
if (store) await store.end();
|
|
69
|
+
await pool.end();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
async function remainingIds(): Promise<string[]> {
|
|
73
|
+
const result = await pool.query<{ id: string }>(
|
|
74
|
+
`SELECT metadata->>'_id' AS id FROM "${tableName}" WHERE metadata->>'marker' = 'seed' ORDER BY id`,
|
|
75
|
+
);
|
|
76
|
+
return result.rows.map((row) => row.id);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
it("deletes only the requested ids with the in operator", async () => {
|
|
80
|
+
if (!available || !store) return;
|
|
81
|
+
await store.delete({ filter: { _id: { in: ["1", "3"] } } });
|
|
82
|
+
await expect(remainingIds()).resolves.toEqual(["2"]);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("leaves every row intact when the in batch matches nothing", async () => {
|
|
86
|
+
if (!available || !store) return;
|
|
87
|
+
await store.delete({ filter: { _id: { in: ["missing"] } } });
|
|
88
|
+
await expect(remainingIds()).resolves.toEqual(["1", "2", "3"]);
|
|
89
|
+
});
|
|
90
|
+
});
|