Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .changeset/knowledge-manifest-turso-origin.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
---
'@objectstack/service-settings': patch
---

Tell the operator where `@objectstack/knowledge-turso` comes from instead of
naming a package this repo does not build

An operator who selects the `turso` knowledge adapter in **Settings → AI &
Embedder** and runs the connection test was told: "Mount
`@objectstack/knowledge-turso` to exercise live calls." That package is in no
directory of this repo (0 path hits on `main`; `knowledge-memory` and
`knowledge-ragflow` return 8 each under the identical command, so the zero is
real), and the message said nothing about where it does come from — leaving the
instruction un-followable at exactly the moment it is read.

The prior question the card turned on — *is it published anywhere?* — is now
measured rather than assumed. Against the public npm registry on 2026-08-23,
with `@objectstack/spec` and `@objectstack/cli` as positive controls and
`@objectstack/security-enterprise` as a known-private negative control:
`@objectstack/knowledge-turso` **is published**, `latest` 6.9.0 (2026-05-27),
nine versions from 6.4.0. So the option stays — dropping it would have deleted a
working adapter.

What it is *not* is co-installable with this platform version: 6.9.0 exact-pins
`@objectstack/spec@6.9.0` while this repo ships 17.2.0, so mounting it resolves a
second spec rather than reusing this one. The runtime message now names the
package, says this platform does not ship it, points at the ObjectStack Cloud
monorepo where it is built, and tells the operator to check for a release
matching their platform version — the framework#3366 discipline that an install
hint must carry its own edition/version boundary.

The manifest's adapter-list comment loses the undated "mirrors the plugin
packages currently published" claim that stopped being true with nothing to
catch it, and gains the measurement with its date and method so the next reader
can re-run it. No behaviour change: `ok` and `severity` are untouched on every
branch of the test action.
Original file line numberDiff line numberDiff line change
Expand Up@@ -97,6 +97,40 @@ describe('knowledgeTestActionHandler', () => {
expect(r.ok).toBe(true);
});

// The turso adapter's plugin package is NOT built in this repo, so the live-call
// hint an operator reads in Settings -> AI & Embedder cannot be a bare "Mount
// @objectstack/knowledge-turso": that instruction was un-followable — it named a
// package with no directory here and no statement of where it comes from. Pinned
// as a property (names the package AND where it ships), not as a literal, so the
// wording can be improved without the guard going stale.
it('turso live-call hint says where the out-of-repo package comes from', async () => {
const r = await knowledgeTestActionHandler({
values: { adapter: 'turso', turso_url: 'file:./knowledge.db' },
} as any);
expect(r.ok).toBe(true);
const message = String(r.message);
expect(message).toContain('@objectstack/knowledge-turso');
expect(message).toMatch(/ObjectStack Cloud monorepo/);
// the un-followable form this card retired: named, with no origin stated
expect(message).not.toMatch(/Mount @objectstack\/knowledge-turso to exercise live calls/);
});

// Contrast, so the assertion above cannot be satisfied by blanket-rewording every
// hint: ragflow's plugin IS built here, and its hint stays the plain mount line.
it('ragflow live-call hint stays a plain mount line (its plugin is built here)', async () => {
const r = await knowledgeTestActionHandler({
values: {
adapter: 'ragflow',
ragflow_base_url: 'http://localhost:9380',
ragflow_api_key: 'k',
},
} as any);
expect(r.ok).toBe(true);
expect(String(r.message)).toContain(
'Mount @objectstack/knowledge-ragflow to exercise live calls',
);
});

it('rejects ragflow without base URL', async () => {
const r = await knowledgeTestActionHandler({
values: { adapter: 'ragflow', ragflow_api_key: 'k' },
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,12 +10,25 @@ import type { SettingsActionHandler } from '../settings-service.types.js';
* knowledge sources and any future agent that needs to embed ad-hoc
* inputs.
*
* Adapter list mirrors the plugin packages currently published:
* - memory @objectstack/knowledge-memory (dev / test reference)
* - turso @objectstack/knowledge-turso (libSQL native F32_BLOB —
* works for cloud Turso AND
* local file mode)
* - ragflow @objectstack/knowledge-ragflow (external RAGFlow service)
* Adapter list — two of these plugin packages are built in this repo and one
* is not, which is the difference that matters to an operator told to mount
* one of them:
* - memory @objectstack/knowledge-memory built here (dev / test ref)
* - ragflow @objectstack/knowledge-ragflow built here (external RAGFlow)
* - turso @objectstack/knowledge-turso NOT built here — libSQL native
* F32_BLOB, works for cloud
* Turso AND local file mode
*
* Spelled out for `turso` because the undated claim that used to stand here —
* "mirrors the plugin packages currently published" — stopped being true and
* nothing caught it. The package IS published on the public npm registry, but
* on its own version track: `latest` was 6.9.0 (published 2026-05-27) while
* this repo shipped 17.2.0, and 6.9.0 exact-pins `@objectstack/spec@6.9.0`, so
* mounting it into an app on this platform version resolves a SECOND spec
* rather than reusing this one. Its source lives in the ObjectStack Cloud
* monorepo (see this repo's README). Measured against the registry on
* 2026-08-23 with `@objectstack/spec` + `@objectstack/cli` as positive
* controls; re-measure before treating those numbers as current.
*
* As with the AI manifest, the real adapter wiring happens in the
* knowledge plugins; this manifest is the canonical settings surface
Expand DownExpand Up@@ -155,7 +168,11 @@ export const knowledgeTestActionHandler: SettingsActionHandler = async ({ values
return {
ok: true,
severity: 'info',
message: `Turso adapter configured (${u}). Mount @objectstack/knowledge-turso to exercise live calls.`,
message:
`Turso adapter configured (${u}). Live calls need @objectstack/knowledge-turso, ` +
'which this platform does not ship: it is built in the ObjectStack Cloud monorepo ' +
'and published on its own version track, so check that it offers a release ' +
'compatible with your platform version before mounting it.',
};
}

Expand Down
Loading