newOS for Developers

Semantic Search

AI-powered semantic search across newOS content using embeddings.

packages/newgraph-signals/src/actions/search.ts

Overview

The search module provides semantic search capabilities that go beyond keyword matching. It uses AI embeddings to understand query intent and find contextually relevant content.

Semantic vs Keyword Search

Unlike traditional keyword search, semantic search understands meaning. A query for "AI assistants" will also match content about "chatbots", "virtual agents", and "automated helpers" even if those exact words aren't used.

semanticSearch

Perform semantic search across indexed content using AI embeddings.

semanticSearch(params?: { q: string })
  : ProgressiveHandlerResponse<Signal<any[]>>
ParameterTypeRequiredDescription
qstringYesNatural language search query

Response Structure

// Response from API
{
  value: SearchResult[]  // Array of matching results
}

// Each SearchResult contains matched content
// ranked by semantic relevance

Features

  • Uses AI embeddings for semantic matching
  • Returns results ranked by relevance score
  • Searches across posts, moods, and user content
  • Auto-starts on initialization when query provided

Usage Example

import { semanticSearch } from "newgraph-signals/actions/search";
import { execProgressiveHandler } from "newgraph-signals";

// Option 1: Initialize with query (autostarts)
const [resultsSignal, progress] = semanticSearch({ q: "AI agents" });
await progress.value.promise;
console.log(resultsSignal.value);

// Option 2: Use execProgressiveHandler
const results = await execProgressiveHandler(semanticSearch, { 
  q: "decentralized social protocol" 
});
console.log(results);

API Query Format

The search API expects a nested query structure:

// Internal API call structure
api.search.semanticList({
  query: {
    query: q  // Natural language query string
  }
})
Note: The double nesting (query.query) is the expected API format.

Underlying API

api.search.semanticList({ query: { query: q } })

GET — Returns semantically matched results ranked by relevance

Reactive Signal

searchResponseSignalSignal<any[]>

Internal signal that holds search results. Updated when search completes. Access via the returned signal from semanticSearch().

React Integration

import { semanticSearch } from "newgraph-signals/actions/search";
import { useSignal } from "@preact/signals-react";
import { useState } from "react";

function SearchComponent() {
  const [query, setQuery] = useState("");
  const [results, progress] = semanticSearch({ q: query });

  const handleSearch = async () => {
    progress.value.exec({ q: query });
    await progress.value.promise;
  };

  return (
    <div>
      <input 
        value={query} 
        onChange={(e) => setQuery(e.target.value)}
        placeholder="Search..."
      />
      <button onClick={handleSearch}>Search</button>
      
      {progress.value.inProgress && <div>Searching...</div>}
      
      <ul>
        {results.value?.map((result, i) => (
          <li key={i}>{result.title}</li>
        ))}
      </ul>
    </div>
  );
}

Notes

Empty Query Handling

If no query is provided (q is empty or undefined), the handler returns early without making an API call. Always provide a non-empty query string.