docs(examples): add metadata filter operator snippets - #438
Conversation
There was a problem hiding this comment.
All reported issues were addressed across 7 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
|
Update: I was able to complete the CLA from another device. The CLA check now shows signed. Thanks. |
There was a problem hiding this comment.
Pull request overview
Adds runnable, copy-pasteable TypeScript examples demonstrating metadata filter operators in the JavaScript examples package (examples/javascript/), aligning with the repo’s goal of providing practical SDK usage snippets.
Changes:
- Added four runnable operator-focused scripts for
$eq,$and,$in, and$nearunderexamples/javascript/metadata-filters/. - Introduced a shared helper to centralize setup (env, temporary index creation/loading), querying, and teardown.
- Updated the JavaScript examples README and
package.jsonscripts to make running the new samples straightforward.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| examples/javascript/README.md | Documents the new metadata filter operator samples and how to run them. |
| examples/javascript/package.json | Adds npm run metadata:* scripts to run each operator snippet. |
| examples/javascript/metadata-filters/shared.ts | Shared runner that creates a temporary index, performs a filtered query, prints results, and cleans up. |
| examples/javascript/metadata-filters/eq.ts | Runnable $eq filter example. |
| examples/javascript/metadata-filters/and.ts | Runnable $and composition example. |
| examples/javascript/metadata-filters/in.ts | Runnable $in filter example. |
| examples/javascript/metadata-filters/near.ts | Runnable $near geo-distance filter example. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codex reviewNo issues found. |
…r-operator-examples
📝 WalkthroughWalkthroughAdded a shared temporary-index runner and four runnable JavaScript examples for ChangesMetadata filter examples
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant OperatorExample
participant runMetadataFilterExample
participant Moss
participant TemporaryIndex
OperatorExample->>runMetadataFilterExample: provide metadata filter
runMetadataFilterExample->>Moss: create temporary index
Moss->>TemporaryIndex: load sample documents
runMetadataFilterExample->>TemporaryIndex: execute filtered hybrid query
TemporaryIndex-->>runMetadataFilterExample: return results
runMetadataFilterExample->>Moss: delete temporary index
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@examples/javascript/metadata-filters/shared.ts`:
- Around line 71-81: Update the temporary index name construction in the
metadata filter example to use randomUUID() as its unique suffix instead of
Date.now(). Keep the existing operator-based prefix and cleanup flow unchanged.
- Around line 102-109: Update the cleanup flow in the surrounding try/finally
logic so deleteIndex’s Promise<boolean> result must be true; when no primary
error exists, propagate cleanup failures by rejecting on a thrown error or a
non-true result. Preserve the primary operation error when both the primary
operation and cleanup fail, and keep the existing cleanupNeeded guard and
warning behavior as appropriate.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: a23bedd1-9a78-45aa-a8e1-d1fc3fc0cde4
📒 Files selected for processing (7)
examples/javascript/README.mdexamples/javascript/metadata-filters/and.tsexamples/javascript/metadata-filters/eq.tsexamples/javascript/metadata-filters/in.tsexamples/javascript/metadata-filters/near.tsexamples/javascript/metadata-filters/shared.tsexamples/javascript/package.json
| const indexName = `metadata-filter-${example.operator.slice(1)}-${Date.now()}`; | ||
| const client = new MossClient(projectId, projectKey); | ||
| let cleanupNeeded = false; | ||
|
|
||
| try { | ||
| console.log(`Moss metadata filter example: ${example.operator}`); | ||
| console.log(example.description); | ||
|
|
||
| console.log(`\nCreating temporary index: ${indexName}`); | ||
| cleanupNeeded = true; | ||
| await client.createIndex(indexName, documents, { modelId: "moss-minilm" }); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- candidate files ---'
git ls-files | rg '(^|/)(package(-lock)?\.json|pnpm-lock\.yaml|yarn\.lock|shared\.ts)$|examples/javascript/metadata-filters'
printf '%s\n' '--- target file ---'
cat -n examples/javascript/metadata-filters/shared.ts | sed -n '1,140p'
printf '%s\n' '--- package references ---'
rg -n --hidden -g '!node_modules' -g '!dist' -g '!build' '`@moss-dev/moss`|moss-dev|MossClient|deleteIndex|createIndex' . | head -250
printf '%s\n' '--- lockfile versions ---'
rg -n --hidden -g 'package.json' -g 'package-lock.json' -g 'pnpm-lock.yaml' -g 'yarn.lock' '`@moss-dev/moss`|1\.3\.0' .Repository: usemoss/moss
Length of output: 50368
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- target directory files ---'
find examples/javascript/metadata-filters -maxdepth 2 -type f -print
printf '%s\n' '--- index lifecycle call sites ---'
rg -n -C 8 'cleanupNeeded|createIndex\(|deleteIndex\(' examples/javascript/metadata-filters
printf '%s\n' '--- dependency manifests and lockfiles ---'
find . -maxdepth 4 -type f \( -name 'package.json' -o -name 'package-lock.json' -o -name 'pnpm-lock.yaml' -o -name 'yarn.lock' \) -printRepository: usemoss/moss
Length of output: 6215
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- examples/javascript dependency declarations ---'
cat examples/javascript/package.json
rg -n -C 4 '"`@moss-dev/moss`"|moss-[0-9]' examples/javascript/package-lock.json
printf '%s\n' '--- SDK package and lifecycle implementation ---'
cat sdks/javascript/sdk/package.json | sed -n '1,180p'
rg -n -C 8 'createIndex|deleteIndex|index already|already exists|Index.*exist|delete.*data' sdks/javascript/sdk/src sdks/javascript/sdk/package.json
printf '%s\n' '--- SDK lockfile package versions ---'
rg -n -C 6 '"`@moss-dev/moss`"|moss-core' sdks/javascript/sdk/package-lock.json | head -160Repository: usemoss/moss
Length of output: 22423
🌐 Web query:
@moss-dev/moss 1.3.0 createIndex deleteIndex existing index name documentation
💡 Result:
In the @moss-dev/moss SDK (v1.3.0 and later), the MossClient provides asynchronous methods for index lifecycle management. createIndex(indexName, docs, options?) The createIndex method initializes, uploads, and builds a new index. It accepts the index name, an array of documents (DocumentInfo[]), and optional configuration such as modelId (defaults to 'moss-minilm') and an onProgress callback [1][2]. Example: await client.createIndex('my-index', [ { id: 'doc-1', text: '...' } ], { modelId: 'moss-minilm' }); Important behavior: The method will throw an error if an index with the specified indexName already exists [2]. deleteIndex(indexName) The deleteIndex method removes an index and all associated data from the project [1][2]. Example: await client.deleteIndex('my-index'); Handling Existing Index Names Because createIndex throws an error if an index name is already in use, you should verify existence or choose a unique name before creation. To update data within an existing index rather than recreating it, use the addDocs method with the upsert option set to true [1]. Example: await client.addDocs('my-index', [ { id: 'doc-2', text: 'updated text' } ], { upsert: true });
Citations:
🏁 Script executed:
#!/bin/bash
set -eu
tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT
curl -fsSL 'https://registry.npmjs.org/@moss-dev/moss/-/moss-1.3.0.tgz' -o "$tmp"
printf '%s\n' '--- package metadata ---'
tar -xOf "$tmp" package/package.json | jq '{name,version,type,exports}'
printf '%s\n' '--- bundled lifecycle behavior ---'
tar -tzf "$tmp" | rg 'dist/.*\.(js|d\.ts)$' | head -30
for path in $(tar -tzf "$tmp" | rg 'dist/.*\.(js|d\.ts)$' | head -20); do
tar -xOf "$tmp" "$path" 2>/dev/null | rg -n -C 3 'already exists|deleteIndex|all its data|createIndex' && printf 'FILE: %s\n' "$path"
doneRepository: usemoss/moss
Length of output: 26262
Use an ownership-safe temporary index name.
If two runs use the same example.operator within one millisecond, Date.now() produces the same index name. createIndex rejects existing names, but cleanupNeeded is already true, so the failed run can delete the other run's index and data.
Use randomUUID() for the suffix.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@examples/javascript/metadata-filters/shared.ts` around lines 71 - 81, Update
the temporary index name construction in the metadata filter example to use
randomUUID() as its unique suffix instead of Date.now(). Keep the existing
operator-based prefix and cleanup flow unchanged.
| } finally { | ||
| if (cleanupNeeded) { | ||
| console.log(`\nDeleting temporary index: ${indexName}`); | ||
| try { | ||
| await client.deleteIndex(indexName); | ||
| } catch (cleanupError) { | ||
| console.warn(`Failed to delete temporary index: ${indexName}`, cleanupError); | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- target file ---'
cat -n examples/javascript/metadata-filters/shared.ts | sed -n '1,150p'
printf '%s\n' '--- repository references ---'
rg -n --glob '!node_modules' --glob '!dist' --glob '!build' \
'runMetadataFilterExample|deleteIndex\(|cleanupNeeded|MossClient' .
printf '%s\n' '--- package and workflow context ---'
git ls-files | rg '(^|/)(package\.json|package-lock\.json|npm-shrinkwrap\.json|yarn\.lock|pnpm-lock\.yaml|README|.*metadata.*filter.*|.*workflow.*)$' | head -200Repository: usemoss/moss
Length of output: 50369
🌐 Web query:
Moss JavaScript SDK MossClient deleteIndex boolean return result documentation
💡 Result:
Moss JavaScript SDK: MossClient.deleteIndex(indexName) returns a Promise. The official JS API reference for MossClient shows: - deleteIndex(indexName): Promise - “Promise that resolves to true if successful” [1]. - It deletes the index and all its data [1]. Example (from docs): const deleted = await client.deleteIndex('old-index'); // deleted is a boolean (true if successful) [1] Notes: - The method throws if the index does not exist [1]. - The docs also describe index deletion at the API level (deleteIndex) as deleting the index record/assets (not changing the JS return type) [2].
Citations:
- 1: https://docs.moss.dev/docs/reference/js/classes/MossClient
- 2: https://docs.moss.dev/docs/api-reference/v1/index-management/deleteIndex
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- JavaScript SDK files ---'
git ls-files | rg '(^|/)(package\.json|package-lock\.json|pnpm-lock\.yaml|yarn\.lock|MossClient|client\.(ts|js)|index\.(ts|js))$' | rg '(^sdks/javascript/|^examples/javascript/|^packages/vitepress-plugin-moss/demo-site/documentation/docs/reference/js/classes/MossClient\.md$|(^|/)package(-lock)?\.json$|pnpm-lock|yarn\.lock)' | head -200
printf '%s\n' '--- local API documentation ---'
cat -n packages/vitepress-plugin-moss/demo-site/documentation/docs/reference/js/classes/MossClient.md | sed -n '150,200p'
printf '%s\n' '--- SDK deleteIndex declarations and implementations ---'
rg -n -A25 -B8 'deleteIndex' sdks/javascript packages/vitepress-plugin-moss/demo-site/documentation/docs/reference/js 2>/dev/null | head -240
printf '%s\n' '--- target example package scripts and dependency pins ---'
find examples/javascript -maxdepth 3 -type f \( -name 'package.json' -o -name 'package-lock.json' -o -name 'pnpm-lock.yaml' -o -name 'yarn.lock' \) -print
rg -n -A8 -B8 '"(`@moss-dev/moss`|metadata-filters)|metadata-filters|runMetadataFilterExample' examples/javascript package.json pnpm-lock.yaml yarn.lock package-lock.json 2>/dev/null | head -240Repository: usemoss/moss
Length of output: 43987
🌐 Web query:
site:docs.moss.dev/docs/reference/js/classes/MossClient deleteIndex Promise<boolean> false return semantics
💡 Result:
In the context of the Moss SDK, the deleteIndex method returns a Promise that resolves to a boolean value [1]. A return value of true indicates that the index was successfully deleted [1]. If the operation fails because the specified index does not exist, the method is documented to throw an error rather than returning false [1]. Semantics for boolean return values in similar asynchronous deletion APIs typically signify the outcome of the requested operation, where true confirms success and false may indicate that the target did not exist or could not be removed, depending on the specific library implementation [1].
Citations:
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- example lockfile resolution ---'
python3 - <<'PY'
import json
p = json.load(open("examples/javascript/package-lock.json"))
for key, value in p.get("packages", {}).items():
if "`@moss-dev/moss`" in key or key == "node_modules/@moss-dev/moss":
print(key, value.get("version"), value.get("resolved"))
print("root dependency:", p["packages"][""].get("dependencies", {}).get("`@moss-dev/moss`"))
PY
printf '%s\n' '--- SDK package metadata ---'
cat -n sdks/javascript/sdk/package.json | sed -n '1,130p'
cat -n sdks/javascript/sdk/src/client/mossClient.ts | sed -n '130,160p'
printf '%s\n' '--- binding implementation references ---'
rg -n -A12 -B8 'deleteIndex' sdks/javascript/bindings sdks/javascript/sdk/src | head -180
printf '%s\n' '--- metadata-filter entrypoint error handling ---'
for f in examples/javascript/metadata-filters/*.ts; do
printf '\n--- %s ---\n' "$f"
cat -n "$f"
doneRepository: usemoss/moss
Length of output: 19387
🌐 Web query:
site:github.com/usemoss/moss "@moss-dev/moss" "deleteIndex" "Promise<boolean>"
💡 Result:
The @moss-dev/moss TypeScript SDK does not provide a method named deleteIndex [1][2]. Based on the official repository documentation and codebase, index management in the Moss ecosystem is typically handled via the Moss CLI [3][4] or through cloud-side administration rather than direct SDK methods intended for index deletion [1][2]. The SDK focuses on operations such as createIndex, loadIndex, and document CRUD (e.g., adding or deleting documents) [1][2][5][6]. For index management tasks like deleting an index, users are generally expected to use the moss CLI tool [3][4] or the Moss Cloud interface [1][2]. If you are attempting to remove an index programmatically, you should verify the current capabilities via the Moss CLI's help commands or the official docs.moss.dev documentation [7][4].
Citations:
- 1: https://github.com/usemoss/moss
- 2: https://github.com/usemoss/moss/blob/main/README.md
- 3: 0a67d4f
- 4: https://github.com/usemoss/moss/blob/main/ROADMAP.md
- 5: feat: add OpenAI Agents SDK cookbook example #146
- 6: [Feature]: Integration with N8N #198
- 7: rebrand: remove remaining @inferedge/moss and inferedge_moss references #161
🏁 Script executed:
#!/bin/bash
set -eu
node - <<'JS'
async function current({ operationError, cleanupResult, cleanupError }) {
let cleanupNeeded = false;
try {
cleanupNeeded = true;
if (operationError) throw new Error("operation");
} finally {
if (cleanupNeeded) {
try {
if (cleanupError) throw new Error("cleanup");
return cleanupResult; // current code ignores this result
} catch {
// current code logs and resolves when the main operation succeeded
}
}
}
}
async function proposed({ operationError, cleanupResult, cleanupError }) {
let cleanupNeeded = false;
let operationSucceeded = false;
try {
cleanupNeeded = true;
if (operationError) throw new Error("operation");
operationSucceeded = true;
} finally {
if (cleanupNeeded) {
try {
if (cleanupError) throw new Error("cleanup");
if (cleanupResult !== true) throw new Error("cleanup returned false");
} catch (error) {
if (operationSucceeded) throw error;
}
}
}
}
for (const scenario of [
["primary failure + cleanup failure", { operationError: true, cleanupError: true }],
["success + cleanup throw", { cleanupError: true }],
["success + false result", { cleanupResult: false }],
["success + true result", { cleanupResult: true }],
]) {
const [name, input] = scenario;
const outcomes = [];
for (const fn of [current, proposed]) {
try {
await fn(input);
outcomes.push("resolve");
} catch (error) {
outcomes.push(`reject:${error.message}`);
}
}
console.log(name, "current=", outcomes[0], "proposed=", outcomes[1]);
}
JSRepository: usemoss/moss
Length of output: 440
Fail when temporary-index cleanup fails without a primary error.
When the primary operation succeeds, reject if deleteIndex throws or returns a value other than true. Preserve the primary error when both operations fail. The pinned @moss-dev/moss 1.3.0 SDK returns Promise<boolean> for deleteIndex.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@examples/javascript/metadata-filters/shared.ts` around lines 102 - 109,
Update the cleanup flow in the surrounding try/finally logic so deleteIndex’s
Promise<boolean> result must be true; when no primary error exists, propagate
cleanup failures by rejecting on a thrown error or a non-true result. Preserve
the primary operation error when both the primary operation and cleanup fail,
and keep the existing cleanupNeeded guard and warning behavior as appropriate.
Summary
$eq,$and,$in, and$nearunderexamples/javascript/metadata-filters/.Closes #417
Verification
npm cinpm run type-checknpm run lintgit diff --checkNotes
The examples require real
MOSS_PROJECT_IDandMOSS_PROJECT_KEYcredentials to run end-to-end. I verified them with the local TypeScript and ESLint checks; at runtime they create a temporary index, run one filtered query, and delete the index.Summary by CodeRabbit
New Features
Documentation
Chores