Skip to content

Commit eca722a

Browse files
committed
fix(tests): update ScopedStorage tests for type safety
1 parent 7a1c2ec commit eca722a

File tree

12 files changed

+137
-133
lines changed

12 files changed

+137
-133
lines changed

packages/knowledge-base/src/knowledge-base/KnowledgeBaseSchema.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,7 @@ export function knowledgeBaseTableNames(kbId: string): {
5656
* Checks whether a KnowledgeBaseRecord uses shared-table mode.
5757
*/
5858
export function isSharedTableMode(record: KnowledgeBaseRecord): boolean {
59-
return record.document_table === SHARED_DOCUMENT_TABLE && record.chunk_table === SHARED_CHUNK_TABLE;
59+
return (
60+
record.document_table === SHARED_DOCUMENT_TABLE && record.chunk_table === SHARED_CHUNK_TABLE
61+
);
6062
}

packages/knowledge-base/src/knowledge-base/ScopedTabularStorage.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ export class ScopedTabularStorage<
3232
Entity = any,
3333
PrimaryKey = any,
3434
InsertType = any,
35-
> implements ITabularStorage<Schema, PrimaryKeyNames, Entity, PrimaryKey, InsertType>
36-
{
35+
> implements ITabularStorage<Schema, PrimaryKeyNames, Entity, PrimaryKey, InsertType> {
3736
protected readonly inner: AnyTabularStorage;
3837
protected readonly kbId: string;
3938
protected readonly events = new EventEmitter<TabularEventListeners<PrimaryKey, Entity>>();
@@ -104,10 +103,7 @@ export class ScopedTabularStorage<
104103
const pageSize = 1000;
105104
let offset = 0;
106105
while (true) {
107-
const page = await this.inner.query(
108-
{ kb_id: this.kbId } as any,
109-
{ offset, limit: pageSize }
110-
);
106+
const page = await this.inner.query({ kb_id: this.kbId } as any, { offset, limit: pageSize });
111107
if (!page || page.length === 0) break;
112108
count += page.length;
113109
if (page.length < pageSize) break;

packages/knowledge-base/src/knowledge-base/ScopedVectorStorage.ts

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ import { ScopedTabularStorage } from "./ScopedTabularStorage";
1919
* post-filtering results by `kb_id`.
2020
*/
2121
export class ScopedVectorStorage<
22-
Metadata extends Record<string, unknown> | undefined,
23-
Schema extends DataPortSchemaObject,
24-
Entity = any,
25-
PrimaryKeyNames extends ReadonlyArray<keyof Schema["properties"]> = ReadonlyArray<
26-
keyof Schema["properties"]
27-
>,
28-
>
22+
Metadata extends Record<string, unknown> | undefined,
23+
Schema extends DataPortSchemaObject,
24+
Entity = any,
25+
PrimaryKeyNames extends ReadonlyArray<keyof Schema["properties"]> = ReadonlyArray<
26+
keyof Schema["properties"]
27+
>,
28+
>
2929
extends ScopedTabularStorage<Schema, PrimaryKeyNames, Entity>
3030
implements IVectorStorage<Metadata, Schema, Entity, PrimaryKeyNames>
3131
{
@@ -47,19 +47,12 @@ export class ScopedVectorStorage<
4747
topK: number | undefined,
4848
overfetchLimit: number | undefined
4949
): (Entity & { score: number })[] {
50-
const filtered = results
51-
.filter((r: any) => r.kb_id === this.kbId)
52-
.slice(0, topK);
50+
const filtered = results.filter((r: any) => r.kb_id === this.kbId).slice(0, topK);
5351

5452
// Only warn when cross-KB filtering is likely the culprit: the inner search
5553
// returned exactly as many results as we requested (overfetch limit) and
5654
// filtering still left us short of topK.
57-
if (
58-
topK &&
59-
overfetchLimit &&
60-
results.length >= overfetchLimit &&
61-
filtered.length < topK
62-
) {
55+
if (topK && overfetchLimit && results.length >= overfetchLimit && filtered.length < topK) {
6356
console.warn(
6457
`ScopedVectorStorage: search returned ${filtered.length}/${topK} results after ` +
6558
`kb_id filtering. Consider increasing overFetchMultiplier (currently ${this.overFetchMultiplier}).`

packages/knowledge-base/src/knowledge-base/SharedTableSchemas.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,14 @@ export type SharedChunkPrimaryKey = typeof SharedChunkPrimaryKey;
7878
* Index definitions for efficient KB-scoped queries on shared document table.
7979
*/
8080
export const SharedDocumentIndexes = [["kb_id"]] as const satisfies readonly (
81-
keyof any | readonly (keyof any)[]
81+
| keyof any
82+
| readonly (keyof any)[]
8283
)[];
8384

8485
/**
8586
* Index definitions for efficient KB-scoped queries on shared chunk table.
8687
*/
87-
export const SharedChunkIndexes = [
88-
["kb_id"],
89-
["kb_id", "doc_id"],
90-
] as const satisfies readonly (keyof any | readonly (keyof any)[])[];
88+
export const SharedChunkIndexes = [["kb_id"], ["kb_id", "doc_id"]] as const satisfies readonly (
89+
| keyof any
90+
| readonly (keyof any)[]
91+
)[];

packages/storage/src/tabular/BaseTabularStorage.ts

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
import { DataPortSchemaObject, FromSchema, TypedArraySchemaOptions } from "@workglow/util/schema";
87
import { createServiceToken, EventEmitter, makeFingerprint } from "@workglow/util";
8+
import { DataPortSchemaObject, FromSchema, TypedArraySchemaOptions } from "@workglow/util/schema";
99
import {
1010
AnyTabularStorage,
1111
AutoGeneratedKeys,
@@ -70,7 +70,7 @@ export abstract class BaseTabularStorage<
7070
protected primaryKeySchema: DataPortSchemaObject;
7171
protected valueSchema: DataPortSchemaObject;
7272

73-
/** Name of the auto-generated key column (only first primary key column can be auto-generated) */
73+
/** Name of the auto-generated key column (at most one primary key column may be auto-generated) */
7474
protected autoGeneratedKeyName: keyof Entity | null = null;
7575
/** Strategy for generating the auto-generated key */
7676
protected autoGeneratedKeyStrategy: KeyGenerationStrategy | null = null;
@@ -165,8 +165,8 @@ export abstract class BaseTabularStorage<
165165
}
166166
}
167167

168-
// Detect and validate auto-generated keys
169-
// Only the first primary key column can be auto-generated
168+
// Detect and validate auto-generated keys (at most one PK column; any PK position is allowed).
169+
// Composite keys often put a scope column first (e.g. kb_id) and auto-generate a second id.
170170
const autoGeneratedKeys: string[] = [];
171171
for (const key of primaryKeyNames) {
172172
const keyStr = String(key);
@@ -181,20 +181,12 @@ export abstract class BaseTabularStorage<
181181
if (autoGeneratedKeys.length > 1) {
182182
throw new Error(
183183
`Multiple auto-generated keys detected: ${autoGeneratedKeys.join(", ")}. ` +
184-
`Only the first primary key column can be auto-generated.`
184+
`At most one primary key column can be auto-generated.`
185185
);
186186
}
187187

188188
if (autoGeneratedKeys.length > 0) {
189189
const autoGenKeyName = autoGeneratedKeys[0];
190-
const firstPrimaryKey = String(primaryKeyNames[0]);
191-
192-
if (autoGenKeyName !== firstPrimaryKey) {
193-
throw new Error(
194-
`Auto-generated key "${autoGenKeyName}" must be the first primary key column. ` +
195-
`Current first primary key is "${firstPrimaryKey}".`
196-
);
197-
}
198190

199191
this.autoGeneratedKeyName = autoGenKeyName as keyof Entity;
200192
this.autoGeneratedKeyStrategy = this.determineGenerationStrategy(

packages/task-graph/src/task-graph/TaskGraph.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,10 @@ export interface TaskGraphRunConfig {
6767
enforceEntitlements?: boolean;
6868
}
6969

70-
export interface TaskGraphRunReactiveConfig
71-
extends Omit<TaskGraphRunConfig, "enforceEntitlements" | "timeout"> {
70+
export interface TaskGraphRunReactiveConfig extends Omit<
71+
TaskGraphRunConfig,
72+
"enforceEntitlements" | "timeout"
73+
> {
7274
/** Optional service registry to use for this task graph */
7375
registry?: ServiceRegistry;
7476
}

packages/task-graph/src/task/EntitlementEnforcer.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,7 @@ export function createPolicyEnforcer(
105105

106106
async checkTask(task: ITask): Promise<readonly TaskEntitlement[]> {
107107
const entitlements = task.entitlements();
108-
return resolveAsks(
109-
entitlements,
110-
(task.constructor as typeof Task).type,
111-
task.id
112-
);
108+
return resolveAsks(entitlements, (task.constructor as typeof Task).type, task.id);
113109
},
114110
};
115111
}

packages/task-graph/src/task/EntitlementPolicy.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
import type { EntitlementGrant, EntitlementId, TaskEntitlement, TaskEntitlements } from "./TaskEntitlements";
7+
import type {
8+
EntitlementGrant,
9+
EntitlementId,
10+
TaskEntitlement,
11+
TaskEntitlements,
12+
} from "./TaskEntitlements";
813
import { entitlementCovers, grantCoversResources } from "./TaskEntitlements";
914

1015
// ========================================================================

packages/tasks/src/task/mcp/McpPromptGetTask.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,7 @@ export class McpPromptGetTask extends Task<
180180

181181
public static override entitlements(): TaskEntitlements {
182182
return {
183-
entitlements: [
184-
{ id: Entitlements.MCP_PROMPT_GET, reason: "Gets prompts from MCP servers" },
185-
],
183+
entitlements: [{ id: Entitlements.MCP_PROMPT_GET, reason: "Gets prompts from MCP servers" }],
186184
};
187185
}
188186

packages/test/src/test/rag/ScopedStorage.test.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
import { InMemoryTabularStorage, InMemoryVectorStorage } from "@workglow/storage";
87
import {
98
createKnowledgeBase,
9+
getGlobalKnowledgeBaseRepository,
1010
isSharedTableMode,
1111
registerKnowledgeBase,
12-
getGlobalKnowledgeBaseRepository,
1312
ScopedTabularStorage,
1413
ScopedVectorStorage,
1514
SharedChunkIndexes,
@@ -19,11 +18,15 @@ import {
1918
SharedDocumentPrimaryKey,
2019
SharedDocumentStorageSchema,
2120
} from "@workglow/knowledge-base";
21+
import { InMemoryTabularStorage, InMemoryVectorStorage } from "@workglow/storage";
2222
import { uuid4 } from "@workglow/util";
2323
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
2424

2525
describe("ScopedTabularStorage", () => {
26-
let sharedStorage: InstanceType<typeof InMemoryTabularStorage>;
26+
let sharedStorage: InMemoryTabularStorage<
27+
typeof SharedDocumentStorageSchema,
28+
typeof SharedDocumentPrimaryKey
29+
>;
2730
let scopeA: ScopedTabularStorage<any, any>;
2831
let scopeB: ScopedTabularStorage<any, any>;
2932

@@ -244,7 +247,10 @@ describe("ScopedTabularStorage", () => {
244247
});
245248

246249
describe("ScopedVectorStorage", () => {
247-
let sharedStorage: InstanceType<typeof InMemoryVectorStorage>;
250+
let sharedStorage: InMemoryVectorStorage<
251+
typeof SharedChunkVectorStorageSchema,
252+
typeof SharedChunkPrimaryKey
253+
>;
248254
let scopeA: ScopedVectorStorage<any, any>;
249255
let scopeB: ScopedVectorStorage<any, any>;
250256

@@ -261,7 +267,7 @@ describe("ScopedVectorStorage", () => {
261267
});
262268

263269
afterEach(() => {
264-
sharedStorage.destroy();
270+
sharedStorage?.destroy?.();
265271
});
266272

267273
test("getVectorDimensions delegates to inner", () => {

0 commit comments

Comments
 (0)