### Run Quickstart Script Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/quickstart.html Execute the `quickstart.ts` file using the Deno runtime. Ensure Deno is installed and the script is in your current directory. ```bash deno run quickstart.ts ``` -------------------------------- ### Complete Setup with Tuning Options Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/quickstart.html Illustrates the complete setup of Semantic Loop with detailed configuration for storage, embedding, selection exploration (epsilon), and outcome aggregation (decayFactor). Includes seeding, selection, and ingestion steps with console logging. ```javascript import { createLoop } from "@semantic-loop/core"; const loop = createLoop({ store: "supabase", // durable storage with vector search embedding: "openai", // semantic similarity selection: { epsilon: 0.2, // 20% chance of exploring instead of exploiting }, aggregation: { decayFactor: 0.9, // recent outcomes matter more }, }); // 1. Seed content with automatic embedding generation await loop.seed([ { content: "The moat is the loop that compounds.", tribe: "founders" }, { content: "Ship fast, learn faster.", tribe: "founders" }, ]); // 2. Select using semantic query — "compounding growth" matches "loop that compounds" const pick = await loop.select("compounding growth strategies", { tribe: "founders", }); // 3. Use the content in your app, post it, send it... console.log(pick.candidate.item.content); // 4. Later, when you have metrics, feed them back const result = await loop.ingest(pick.candidate.item.id, "twitter", { views: 8500, likes: 120, shares: 34, clicks: 210, }); // 5. Next select() is smarter. The loop compounds. ``` -------------------------------- ### SupabaseRpcStore Usage Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/api.html Example of how to instantiate and configure the SupabaseRpcStore for production environments. ```APIDOC ## SupabaseRpcStore Usage ### Description Shows how to initialize the `SupabaseRpcStore`, which uses Supabase (PostgreSQL + pgvector) for durable, scalable data storage and vector similarity search. ### Code Example ```javascript import { SupabaseRpcStore } from "@semantic-loop/core"; const store = new SupabaseRpcStore({ url: "https://your-project.supabase.co", serviceRoleKey: "your-key", }); // Optional: Specify table names if they differ from defaults // const storeWithOptions = new SupabaseRpcStore({ // url: "https://your-project.supabase.co", // serviceRoleKey: "your-key", // itemsTable: "my_items", // aggregatesTable: "my_scores", // }); ``` ### Options - `url`: Supabase project URL. - `serviceRoleKey`: Supabase service role key for backend access. - `itemsTable` (optional): Name of the table for semantic items (defaults to `semantic_items`). - `aggregatesTable` (optional): Name of the table for aggregate scores (defaults to `semantic_item_scores`). - `rpc` (optional): Partial configuration for RPC function names. - `fetcher` (optional): Injectable `fetch` function for testing. ``` -------------------------------- ### Create a Semantic Loop with Default Memory Store Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/api.html Use `createLoop()` with a string shorthand for the store to initialize a loop with default settings. This is the simplest way to get started. ```typescript createLoop({ store: "memory" }) ``` -------------------------------- ### Install Semantic Loop (Deno) Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/llms-full.txt Import the `createLoop` function from the core package for Deno projects. ```typescript import { createLoop } from "jsr:@semantic-loop/core"; ``` -------------------------------- ### Quickstart: In-Memory Loop Initialization and Usage Source: https://github.com/cemphlvn/semantic-loop/blob/main/README.md Demonstrates initializing a semantic loop using in-memory storage for local development. It covers seeding content, selecting the best candidate, ingesting outcome data, and performing another selection informed by the results. ```typescript import { createLoop } from "@semantic-loop/core"; // In-memory — no external services needed const loop = createLoop({ store: "memory" }); await loop.seed([ { content: "Why most founders build features when they should build feedback loops." }, { content: "Generic productivity advice." }, { content: "The moat is the loop that compounds after every post." }, ]); // Select best candidate const pick = await loop.select(); console.log(pick.candidate.item.content); // Simulate real-world outcome const result = await loop.ingest(pick.candidate.item.id, "instagram", { views: 12400, likes: 340, comments: 45, shares: 89, }); console.log(result.finalScore); // 0.341 // Select again — now informed by the outcome const next = await loop.select(); // → picks the item that performed, not random ``` -------------------------------- ### InMemoryStore Usage Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/api.html Example of how to instantiate and use the InMemoryStore for testing and prototyping. ```APIDOC ## InMemoryStore Usage ### Description Demonstrates the instantiation and basic usage of the `InMemoryStore`, which is suitable for testing and development environments as it stores data in memory. ### Code Example ```javascript import { InMemoryStore } from "@semantic-loop/core"; const store = new InMemoryStore(); // Example of using upsertItem (assuming SemanticItem is defined elsewhere) // await store.upsertItem({ id: 'item1', content: 'This is a test item' }); // Example of using retrieve (assuming RetrieveRequest is defined elsewhere) // const candidates = await store.retrieve({ query: 'test', limit: 5 }); // console.log(candidates); ``` ### Notes - Data is lost when the process exits. - Accepts an optional `now?: () => Date` constructor argument for deterministic testing. ``` -------------------------------- ### Supabase Environment Variables Setup Source: https://github.com/cemphlvn/semantic-loop/blob/main/README.md Sets the required environment variables for connecting to Supabase and optionally for OpenAI embeddings. ```bash SUPABASE_URL=https://your-project.supabase.co SUPABASE_SERVICE_ROLE_KEY=your-key OPENAI_API_KEY=sk-... # optional, for embeddings ``` -------------------------------- ### Create an In-Memory Loop and Seed Content Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/quickstart.html Initialize a Semantic Loop with an in-memory store and seed it with initial content. This example demonstrates basic setup without external services. ```typescript import { createLoop } from "@semantic-loop/core"; // in-memory store, no external services const loop = createLoop({ store: "memory" }); // seed content await loop.seed([ { content: "The moat is the loop that compounds after every post.", tribe: "founders", kind: "hook" }, { content: "Generic productivity advice.", tribe: "founders", kind: "hook" }, { content: "Why most founders build features when they should build feedback loops.", tribe: "founders", kind: "hook" }, ]); ``` -------------------------------- ### Full Semantic Loop API Example Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/index.html Demonstrates the complete workflow of seeding content, selecting the best item for a given context, and ingesting feedback to improve future selections. The loop automatically generates variations of successful items. ```javascript const loop = createLoop({ store: "supabase", embedding: "openai" }); // 1. Seed content — embeddings are generated automatically await loop.seed([{ content: "Your hook here", tribe: "founders" }]); // 2. Select the best item for this context const pick = await loop.select("growth strategies"); // 3. Later: feed back what happened await loop.ingest(pick.candidate.item.id, "instagram", { views: 12400, likes: 340, shares: 89, }); // Next select() is smarter. Every loop compounds. // If the item scored well, the breeder generates variations automatically. ``` -------------------------------- ### Production Setup with Supabase and OpenAI Embeddings Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/llms-full.txt Configures Semantic Loop for production using Supabase for storage and OpenAI for embeddings, integrated within a Deno.serve() edge function. Handles '/select' and '/webhook' endpoints. ```typescript import { createLoop, json, methodNotAllowed, verifyHmacSignature } from "jsr:@semantic-loop/core"; const loop = createLoop({ store: "supabase", embedding: "openai", }); Deno.serve(async (req) => { const url = new URL(req.url); if (url.pathname === "/select" && req.method === "POST") { const { query, tribe, kind } = await req.json(); const pick = await loop.select(query, { tribe, kind }); return json({ content: pick.candidate.item.content, id: pick.candidate.item.id, strategy: pick.strategy, score: pick.weightedScore, }); } if (url.pathname === "/webhook" && req.method === "POST") { const body = await req.text(); const sig = req.headers.get("x-signature") ?? ""; const secret = Deno.env.get("WEBHOOK_SECRET") ?? ""; if (secret) { const ok = await verifyHmacSignature({ body, signature: sig, secret }); if (!ok) return json({ error: "Invalid signature" }, 401); } const payload = JSON.parse(body); const result = await loop.ingest( payload.itemId, payload.platform, payload.metrics, ); return json({ ok: true, scoreAvg: result.aggregate.scoreAvg, attempts: result.aggregate.attempts, }); } return methodNotAllowed(["POST"]); }); ``` -------------------------------- ### Seed Loop with Initial Content Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/quickstart.html Populates the loop with initial content items. Each item has content, a tribe, and a kind. This is the starting point for the loop's learning process. ```typescript await loop.seed([ { content: "The moat is the loop that compounds after every post.", tribe: "founders", kind: "hook" }, { content: "Generic productivity advice.", tribe: "founders", kind: "hook" }, { content: "Why most founders build features when they should build feedback loops.", tribe: "founders", kind: "hook" }, ]); ``` -------------------------------- ### HeuristicCritic Usage Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/api.html Example of how to instantiate and configure the HeuristicCritic. ```APIDOC ## HeuristicCritic Usage ### Description Provides examples of initializing the `HeuristicCritic`, which uses keyword-based logic for scoring semantic items. It can be configured with custom keyword lists. ### Code Example ```javascript import { HeuristicCritic } from "@semantic-loop/core"; // Default HeuristicCritic const critic = new HeuristicCritic(); // HeuristicCritic with custom keywords const criticWithCustomKeywords = new HeuristicCritic({ noveltyKeywords: ["why", "hidden", "counterintuitive"], penaltyKeywords: ["viral", "guaranteed"], }); ``` ``` -------------------------------- ### Production createLoop Configuration with Supabase and OpenAI Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/index.html Configures Semantic Loop for production use with Supabase as the store and OpenAI for embeddings. This setup provides persistent storage and robust vectorization. ```javascript const loop = createLoop({ store: "supabase", embedding: "openai", }); ``` -------------------------------- ### Initialize Loop with Memory Store Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/quickstart.html Creates a new loop instance using the in-memory store. This is suitable for quick testing and development as it requires no external setup. ```typescript import { createLoop } from "@semantic-loop/core"; const loop = createLoop({ store: "memory" }); ``` -------------------------------- ### Create Semantic Loop Factory Source: https://context7.com/cemphlvn/semantic-loop/llms.txt Use `createLoop` to set up a Semantic Loop instance. It resolves string shorthands for common configurations or accepts detailed object configurations for storage, embedding, critiquing, and selection parameters. Production setups may require environment variables for service credentials. ```typescript import { createLoop } from "@semantic-loop/core"; // --- Minimal (in-memory, no external services) --- const loop = createLoop({ store: "memory" }); // --- Production (Supabase + OpenAI, reads from env) --- // Requires: SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, OPENAI_API_KEY const prodLoop = createLoop({ store: "supabase", embedding: "openai", }); // --- Fully tuned --- const tunedLoop = createLoop({ store: { provider: "supabase", url: Deno.env.get("SUPABASE_URL")!, serviceRoleKey: Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!, }, embedding: { provider: "openai", apiKey: Deno.env.get("OPENAI_API_KEY")!, model: "text-embedding-3-small", dimensions: 1536, }, critic: { provider: "heuristic", noveltyKeywords: ["why", "mistake", "counterintuitive"], penaltyKeywords: ["viral", "guaranteed"], }, selection: { epsilon: 0.2, // 20% explore freshnessHalfLifeHours: 48, weights: { similarity: 0.35, scoreAvg: 0.4, exploration: 0.15, freshness: 0.1 }, }, aggregation: { decayFactor: 0.9 }, breeding: { scoreThreshold: 0.75, maxChildrenPerBreed: 2 }, }); ``` -------------------------------- ### Create Loop with Supabase Store (Explicit Configuration) Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/quickstart.html Initialize the loop with Supabase storage by explicitly providing environment variables for URL and service role key. This offers more control over configuration. ```javascript const loop = createLoop({ store: { provider: "supabase", url: Deno.env.get("SUPABASE_URL")!, serviceRoleKey: Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!, }, }); ``` -------------------------------- ### Initialize SupabaseRpcStore Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/api.html Instantiate the SupabaseRpcStore for durable storage using Supabase. Requires Supabase project URL and service role key. ```typescript import { SupabaseRpcStore } from "@semantic-loop/core"; const store = new SupabaseRpcStore({ url: "https://your-project.supabase.co", serviceRoleKey: "your-key", }); ``` -------------------------------- ### Initialize and Use SupabaseRpcStore Source: https://context7.com/cemphlvn/semantic-loop/llms.txt Set up SupabaseRpcStore for a production Postgres backend with pgvector. Requires specific SQL migrations and Supabase credentials. Supports item upserts and semantic retrieval. ```ts import { SupabaseRpcStore } from "@semantic-loop/core"; const store = new SupabaseRpcStore({ url: Deno.env.get("SUPABASE_URL")!, serviceRoleKey: Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!, // Optional overrides: itemsTable: "semantic_items", // default aggregatesTable: "semantic_item_scores", // default rpc: { upsertItem: "sl_upsert_item", // default matchItems: "sl_match_items", recordOutcome: "sl_record_outcome", applyOutcome: "sl_apply_outcome", }, // fetcher: customFetch, // for testing / edge proxies }); // Upsert an item with its embedding await store.upsertItem({ id: "item-001", tribe: "founders", kind: "hook", content: "The loop that compounds.", embedding: Array(1536).fill(0.01), // 1536-dim vector metadata: { campaign: "q1" }, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }); // Semantic retrieval via pgvector cosine distance const candidates = await store.retrieve({ tribe: "founders", queryVector: Array(1536).fill(0.01), limit: 8, minSimilarity: 0.3, includeArchived: false, }); console.log(candidates[0].item.id); // "item-001" console.log(candidates[0].aggregate.scoreAvg); // 0 ``` -------------------------------- ### Create Loop with Raw SupabaseRpcStore Instance Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/quickstart.html Initialize the loop with a raw SupabaseRpcStore instance for full control over table names, RPC function names, and the fetch implementation. This is useful for advanced customization. ```javascript import { createLoop, SupabaseRpcStore } from "@semantic-loop/core"; const store = new SupabaseRpcStore({ url: "https://your-project.supabase.co", serviceRoleKey: "your-key", itemsTable: "semantic_items", // default aggregatesTable: "semantic_item_scores", // default rpc: { upsertItem: "sl_upsert_item", // default matchItems: "sl_match_items", // default recordOutcome: "sl_record_outcome", // default applyOutcome: "sl_apply_outcome", // default }, }); const loop = createLoop({ store }); ``` -------------------------------- ### Select Endpoint Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/supabase.html An example of a Supabase edge function for selecting content based on a query. ```APIDOC ## POST /select This endpoint selects the best content for an API call based on a query. ### Description Handles POST requests to the `/select` endpoint. It uses the Semantic Loop core to query for relevant content based on provided parameters. ### Method POST ### Endpoint `/select` ### Parameters #### Request Body - **query** (string) - Optional - The search query. - **tribe** (string) - Optional - The tribe to filter by. - **kind** (string) - Optional - The kind of content to select. ### Request Example ```json { "query": "What is the best way to learn a new language?", "tribe": "language-learning", "kind": "article" } ``` ### Response #### Success Response (200) - **content** (string) - The selected content. - **id** (string) - The ID of the selected content. - **strategy** (string) - The strategy used for selection. - **score** (number) - The weighted score of the selection. #### Response Example ```json { "content": "Learning a new language can be achieved through immersion, consistent practice, and utilizing language learning apps.", "id": "content-123", "strategy": "semantic-similarity", "score": 0.95 } ``` ``` -------------------------------- ### Default Configuration Constants Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/llms-full.txt Provides default configuration values for selection, aggregation, and loop parameters. These can be used as starting points or for reference. ```typescript // Default configs const DEFAULT_SELECTION_CONFIG: SelectionConfig // epsilon: 0.18, topKExplorationPool: 3, freshnessHalfLifeHours: 168 // weights: { similarity: 0.45, scoreAvg: 0.35, exploration: 0.15, freshness: 0.05 } const DEFAULT_AGGREGATION_CONFIG: AggregationConfig // criticWeight: 0.6, engagementWeight: 0.4, decayFactor: 0.95 const DEFAULT_LOOP_CONFIG: LoopConfig ``` -------------------------------- ### Supabase Edge Function for Select Endpoint Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/supabase.html An example of a Supabase edge function that handles POST requests to select data. It uses createLoop for store and embedding configuration. ```typescript import { createLoop } from "@semantic-loop/core"; import { readJson, json, methodNotAllowed } from "@semantic-loop/core/runtime/edge"; const loop = createLoop({ store: "supabase", embedding: "openai" }); Deno.serve(async (req) => { if (req.method !== "POST") return methodNotAllowed(["POST"]); const { query, tribe, kind } = await readJson<{ query?: string; tribe?: string; kind?: string; }>(req); const pick = await loop.select(query, { tribe, kind }); return json({ content: pick.candidate.item.content, id: pick.candidate.item.id, strategy: pick.strategy, score: pick.weightedScore, }); }); ``` -------------------------------- ### OpenAIEmbedding Initialization Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/api.html Demonstrates how to initialize the OpenAIEmbedding class with default and custom parameters. ```APIDOC ## OpenAIEmbedding Initialization ### Description Initializes an instance of the OpenAIEmbedding class. You can provide an API key and optionally specify the model, dimensions, and base URL for the OpenAI API. ### Usage ```javascript import { OpenAIEmbedding } from "@semantic-loop/core"; // Initialize with default model and dimensions const embedder = new OpenAIEmbedding({ apiKey: "sk-..." }); // Initialize with custom model, dimensions, and base URL const embedder2 = new OpenAIEmbedding({ apiKey: "sk-...", model: "text-embedding-3-small", dimensions: 1536, baseUrl: "https://api.openai.com/v1", }); ``` ### Parameters - `apiKey` (string) - Required - Your OpenAI API key. - `model` (string) - Optional - The OpenAI embedding model to use. Defaults to `text-embedding-3-small`. - `dimensions` (number) - Optional - The desired dimensions for the embeddings. Defaults to 1536. - `baseUrl` (string) - Optional - The base URL for the OpenAI API. Useful for Azure OpenAI or proxy endpoints. ``` -------------------------------- ### Ingest Outcome and Get Final Score Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/quickstart.html Ingest the real-world outcome of a selected item to provide feedback. The system calculates a final score based on the provided metrics. ```typescript const result = await loop.ingest(pick.candidate.item.id, "instagram", { views: 12400, likes: 340, comments: 45, shares: 89, }); console.log(result.finalScore); ``` -------------------------------- ### Full Production Loop Cycle Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/quickstart.html Demonstrates a complete production loop cycle including seeding content, selecting based on a semantic query, and ingesting outcomes to improve future selections. Uses Supabase for storage and OpenAI for embeddings. ```javascript import { createLoop } from "@semantic-loop/core"; const loop = createLoop({ store: "supabase", embedding: "openai", selection: { epsilon: 0.2 }, aggregation: { decayFactor: 0.9 }, }); // seed await loop.seed([ { content: "The moat is the loop that compounds.", tribe: "founders" }, { content: "Ship fast, learn faster.", tribe: "founders" }, ]); // select with semantic query const pick = await loop.select("compounding growth strategies", { tribe: "founders", }); // publish pick.candidate.item.content to your platform... // later: ingest the outcome await loop.ingest(pick.candidate.item.id, "twitter", { views: 8500, likes: 120, shares: 34, clicks: 210, }); ``` -------------------------------- ### Minimal createLoop Configuration Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/index.html Sets up a basic Semantic Loop instance using an in-memory store without embeddings. Ideal for testing or simple use cases. ```javascript const loop = createLoop({ store: "memory", }); ``` -------------------------------- ### Explicit Embedding Configuration with OpenAI Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/quickstart.html Configure OpenAI embeddings with explicit control over the model, dimensions, and API base URL. Ensure the 'dimensions' match your pgvector column definition. This allows for custom setups like Azure OpenAI. ```javascript const loop = createLoop({ store: "supabase", embedding: { provider: "openai", apiKey: Deno.env.get("OPENAI_API_KEY")!, model: "text-embedding-3-small", // default dimensions: 1536, // default — match your pgvector column baseUrl: "https://api.openai.com/v1", // default — change for Azure, proxies }, }); ``` -------------------------------- ### Adapters Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/llms-full.txt Implementations of the `MemoryStore` interface for different environments. ```APIDOC ## Adapters ### Description Provides concrete implementations of the `MemoryStore` interface, catering to different use cases such as testing and production environments. ### Classes #### InMemoryStore implements MemoryStore An in-memory implementation of `MemoryStore`, suitable for testing and development. ##### constructor(now?: () => Date) Initializes the `InMemoryStore` with an optional date provider. #### SupabaseRpcStore implements MemoryStore A production-ready implementation of `MemoryStore` using Supabase RPC for data persistence. ##### constructor(options: { url: string; serviceRoleKey: string; itemsTable?: string; aggregatesTable?: string; rpc?: Partial<{ upsertItem: string; matchItems: string; recordOutcome: string; applyOutcome: string; }>; fetcher?: typeof fetch; }) Initializes the `SupabaseRpcStore` with Supabase connection details and optional table/RPC names. ``` -------------------------------- ### Explicit Supabase Configuration Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/supabase.html Create a Semantic Loop instance with explicit Supabase store and OpenAI embedding configurations, bypassing environment variables. ```javascript const loop = createLoop({ store: { provider: "supabase", url: "https://your-project.supabase.co", serviceRoleKey: "eyJ...", }, embedding: { provider: "openai", apiKey: "sk-...", }, }); ``` -------------------------------- ### Initialize Loop with Supabase and OpenAI Source: https://github.com/cemphlvn/semantic-loop/blob/main/README.md Initializes the semantic loop with Supabase for storage and OpenAI for embeddings. Ensure SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, and OPENAI_API_KEY environment variables are set. ```typescript import { createLoop } from "@semantic-loop/core"; const loop = createLoop({ store: "supabase", embedding: "openai" }); await loop.seed([ { content: "The moat is the loop that compounds.", tribe: "founders" }, ]); const pick = await loop.select("compounding growth strategies"); await loop.ingest(pick.candidate.item.id, "instagram", { views: 12400, likes: 340, shares: 89, }); // Next select() is smarter. Every loop compounds. ``` -------------------------------- ### Basic Semantic Loop Usage Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/llms-full.txt Demonstrates creating a loop with memory storage, seeding initial items, selecting the best item for a given context, and ingesting feedback results. ```typescript import { createLoop } from "jsr:@semantic-loop/core"; // 1. Create the loop — wires store, embeddings, critic from config const loop = createLoop({ store: "memory" }); // 2. Seed items (embeddings generated automatically if embedding provider configured) await loop.seed([ { content: "The hidden moat nobody talks about: compounding feedback loops", tribe: "ai-founders", kind: "hook", }, // ... more items ]); // 3. Select the best item for this context const pick = await loop.select("growth strategies", { tribe: "ai-founders" }); console.log(pick.candidate.item.content); // The winning hook console.log(pick.strategy); // "greedy" or "explore" console.log(pick.weightedScore); // 0.0 to 1.0 // 4. Later: feed back real-world results const result = await loop.ingest(pick.candidate.item.id, "instagram", { views: 12400, likes: 340, comments: 28, shares: 89, saves: 214, }); console.log(result.finalScore); // Combined critic + engagement console.log(result.aggregate.scoreAvg); // Running average console.log(result.aggregate.attempts); // Total selections ``` -------------------------------- ### Initialize Loop with Supabase Configuration Source: https://github.com/cemphlvn/semantic-loop/blob/main/README.md Initializes the semantic loop using Supabase for storage and OpenAI for embeddings, referencing the environment variables set for connection details. ```typescript const loop = createLoop({ store: "supabase", embedding: "openai" }); ``` -------------------------------- ### Create Semantic Loop Instance Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/llms-full.txt Use `createLoop` as the recommended entry point to instantiate a Semantic Loop. Configure its behavior by providing a `LoopDefinition` object. ```typescript import { createLoop } from "jsr:@semantic-loop/core"; function createLoop(definition: LoopDefinition): SemanticLoop; ``` -------------------------------- ### Add Semantic Loop Core to Deno Project Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/index.html Use this command to add the core library to your Deno project. This is the first step to integrating Semantic Loop. ```bash `deno add jsr:@semantic-loop/core` ``` -------------------------------- ### Create a Semantic Loop with Supabase, OpenAI, and Heuristic Critic Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/api.html Initialize a loop using Supabase for storage, OpenAI for embeddings, and a heuristic critic. This configuration leverages specific implementations for each component. ```typescript createLoop({ store: "supabase", embedding: "openai", critic: "heuristic" }) ``` -------------------------------- ### LoopDefinition Configuration Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/api.html The configuration object passed to `createLoop()`. Only `store` is required. Each config slot uses a union type allowing string shorthand, typed config object, or raw interface instance. String shorthands read env vars via `Deno.env.get()`. Missing env vars throw `ValidationError` with a descriptive message. ```APIDOC ## `LoopDefinition` Interface ### Description Defines the configuration for a loop, specifying storage, embedding, and critic strategies. ### Fields - **`store`** (string | { provider: "supabase", url: string, serviceRoleKey: string } | { provider: "memory" } | MemoryStore) - Required - Where items live. Use `"memory"` for testing, `"supabase"` for production. - **`embedding`** (string | { provider: "openai", apiKey: string, model?: string, dimensions?: number, baseUrl?: string } | EmbeddingProvider) - Optional - How text becomes vectors. Use `"openai"` or omit for no embeddings. - **`critic`** (string | { provider: "heuristic", noveltyKeywords?: string[], penaltyKeywords?: string[] } | Critic) - Optional - How items are scored. Defaults to `"heuristic"` (keyword-based). - **`selection`** (Partial) - Optional - Tune selection: epsilon, weights, freshness half-life. - **`aggregation`** (Partial) - Optional - Tune aggregation: decay factor, critic/engagement weights. - **`telemetry`** (Telemetry) - Optional - Plug in tracing (OpenTelemetry, Datadog). Defaults to no-op. ``` -------------------------------- ### Create a Semantic Loop with Supabase and OpenAI Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/api.html Configure `createLoop()` to use Supabase for storage and OpenAI for embeddings by providing string shorthands. Environment variables are used for credentials. ```typescript createLoop({ store: "supabase", embedding: "openai" }) ``` -------------------------------- ### loop.select(query?, opts?) Source: https://context7.com/cemphlvn/semantic-loop/llms.txt Embeds the optional query string, retrieves candidates from the store, and applies epsilon-greedy selection. Returns a `SelectedCandidate` with `.candidate`, `.strategy` (`"greedy"` | `"explore"`), and `.weightedScore`. ```APIDOC ## `loop.select(query?, opts?)` — pick the best candidate Embeds the optional query string, retrieves candidates from the store, and applies epsilon-greedy selection. Returns a `SelectedCandidate` with `.candidate`, `.strategy` (`"greedy"` | `"explore"`), and `.weightedScore`. ### Parameters - **query** (string, optional) - The semantic query string to filter candidates. - **opts** (object, optional) - Options for selection: - **tribe** (string) - Filter candidates by tribe. - **kind** (string) - Filter candidates by kind. - **limit** (number) - Retrieve top-N candidates before selection. - **minSimilarity** (number) - Filter by minimum cosine similarity. - **selection** (object) - Override selection configuration: - **epsilon** (number) - Exploration rate. - **weights** (object) - Weights for different scoring factors (similarity, scoreAvg, exploration, freshness). ### Request Example ```ts import { createLoop } from "@semantic-loop/core"; const loop = createLoop({ store: "memory" }); await loop.seed([ { content: "Hook A: contrarian take on productivity.", tribe: "founders", kind: "hook" }, { content: "Hook B: step-by-step guide.", tribe: "founders", kind: "hook" }, { content: "Hook C: counterintuitive framework.", tribe: "founders", kind: "hook" }, ]); // Select without a query — relies on exploration + freshness const pick1 = await loop.select(); console.log(pick1.candidate.item.content); console.log(pick1.strategy); console.log(pick1.weightedScore); // Select with semantic query (requires embedding provider) const prodLoop = createLoop({ store: "memory", embedding: "openai" }); const pick2 = await prodLoop.select("compounding growth strategies", { tribe: "founders", kind: "hook", limit: 5, minSimilarity: 0.3, }); console.log(pick2.candidate.item.content); // Override selection config per-call const pick3 = await loop.select(undefined, { selection: { epsilon: 0, weights: { similarity: 0, scoreAvg: 1, exploration: 0, freshness: 0 } }, }); ``` ### Response #### Success Response - **candidate** (object) - The selected candidate item. - **strategy** (string) - The selection strategy used (`"greedy"` or `"explore"`). - **weightedScore** (number) - The final score of the selected candidate. ``` -------------------------------- ### Minimal Configuration for Local Development Source: https://github.com/cemphlvn/semantic-loop/blob/main/README.md Configures the semantic loop to use in-memory storage, suitable for local development and testing without external dependencies. ```typescript const loop = createLoop({ store: "memory" }); ``` -------------------------------- ### createLoop Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/llms.txt The recommended entry point for creating a Semantic Loop instance. It accepts a declarative configuration object to set up stores, embedding providers, critics, selection strategies, and aggregation methods. ```APIDOC ## createLoop ### Description This function is the primary entry point for initializing and configuring a Semantic Loop. It takes a `LoopDefinition` object that specifies various components like the data store, embedding model, critic strategy, and more. ### Signature `createLoop(definition: LoopDefinition): SemanticLoop` ### Parameters #### `definition` (LoopDefinition) - Required An object containing the configuration for the Semantic Loop. This includes: - `store`: Specifies the data store to use (e.g., "memory" for testing, "supabase" for production, or a custom `MemoryStore` instance). - `embedding`: Configures the embedding provider (e.g., "openai" for production, or omitted for no auto-embedding). - `critic`: Defines the critic strategy (e.g., `HeuristicCritic` (default), `LlmCritic`, `MultiSignalCritic`). - `breeder`: Controls how the pool of items grows. Defaults to `NoopBreeder` (static pool), but can be a custom breeder for generating variations. - `selection`: Configuration for the selection algorithm, including epsilon-greedy strategy and weighted scoring parameters. - `aggregation`: Settings for aggregation, including decay-weighted updates. ### Returns - `SemanticLoop`: An instance of the Semantic Loop engine, ready to be used for seeding, selecting, and ingesting. ``` -------------------------------- ### Production Configuration for Supabase and OpenAI Source: https://github.com/cemphlvn/semantic-loop/blob/main/README.md Sets up the semantic loop for production use with Supabase for data storage and OpenAI for generating embeddings. Requires SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, and OPENAI_API_KEY environment variables. ```typescript const loop = createLoop({ store: "supabase", // reads SUPABASE_URL + SUPABASE_SERVICE_ROLE_KEY embedding: "openai", // reads OPENAI_API_KEY }); ``` -------------------------------- ### Initialize OpenAIEmbedding Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/api.html Instantiate the OpenAIEmbedding class with an API key. Supports custom model, dimensions, and base URL for Azure OpenAI or compatible APIs. Batch embedding is handled efficiently. ```javascript import { OpenAIEmbedding } from "@semantic-loop/core"; const embedder = new OpenAIEmbedding({ apiKey: "sk-..." }); ``` ```javascript const embedder2 = new OpenAIEmbedding({ apiKey: "sk-...", model: "text-embedding-3-small", dimensions: 1536, baseUrl: "https://api.openai.com/v1", }); ``` -------------------------------- ### createLoop() Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/api.html The main entry point for creating a SemanticLoop instance. It wires together storage, embedding, and critic components based on the provided definition. Sensible defaults are used for most configurations. ```APIDOC ## createLoop() ### Description The main entry point. Wires together a store, embedding provider, critic, and configuration into a ready-to-use loop. ### Signature `function createLoop(definition: LoopDefinition): SemanticLoop` ### Parameters * **definition** (`LoopDefinition`) - An object that specifies the backend for storage, embedding generation, and algorithm tuning. ### Examples ```javascript createLoop({ store: "memory" }) createLoop({ store: "supabase", embedding: "openai" }) createLoop({ store: "supabase", embedding: "openai", critic: "heuristic" }) createLoop({ store: "supabase", selection: { epsilon: 0.25 }, aggregation: { decayFactor: 0.9 } }) ``` ### Returns A `SemanticLoop` object with `seed()`, `select()`, and `ingest()` methods. ``` -------------------------------- ### Initialize Supabase Schema for Semantic Loop Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/docs/supabase.html This SQL script creates the necessary tables and extensions for the semantic-loop project in Supabase. It defines tables for items, scores, and outcomes, and enables the vector extension for embedding storage. ```sql create extension if not exists vector; create table if not exists public.semantic_items ( id text primary key, tribe text not null, kind text not null, content text not null, embedding vector(1536) not null, metadata jsonb not null default '{}'::jsonb, created_at timestamptz not null default now(), updated_at timestamptz not null default now(), archived_at timestamptz ); create table if not exists public.semantic_item_scores ( item_id text primary key references public.semantic_items(id) on delete cascade, attempts integer not null default 0, score_sum double precision not null default 0, score_avg double precision not null default 0, critic_avg double precision not null default 0, engagement_avg double precision not null default 0, last_score double precision, last_critic_score double precision, last_engagement_score double precision, last_outcome_at timestamptz, updated_at timestamptz not null default now() ); create table if not exists public.semantic_outcomes ( id text primary key, item_id text not null references public.semantic_items(id) on delete cascade, platform text not null, occurred_at timestamptz not null, metrics jsonb not null default '{}'::jsonb, payload jsonb not null default '{}'::jsonb, engagement_score double precision not null, critic_score double precision not null, final_score double precision not null, rationale text, tags text[] not null default '{}', meta jsonb not null default '{}'::jsonb, created_at timestamptz not null default now() ); ``` -------------------------------- ### SupabaseRpcStore Adapter Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/llms-full.txt A production-ready MemoryStore adapter that uses Supabase RPC for data persistence. Configure with Supabase project details and table/RPC names. ```typescript // Production class SupabaseRpcStore implements MemoryStore { constructor(options: { url: string; serviceRoleKey: string; itemsTable?: string; // "semantic_items" aggregatesTable?: string; // "semantic_item_scores" rpc?: Partial<{ upsertItem: string; // "sl_upsert_item" matchItems: string; // "sl_match_items" recordOutcome: string; // "sl_record_outcome" applyOutcome: string; // "sl_apply_outcome" }>; fetcher?: typeof fetch; }) } ``` -------------------------------- ### Instantiate SemanticLoopEngine Directly Source: https://context7.com/cemphlvn/semantic-loop/llms.txt Instantiate the SemanticLoopEngine directly for full control over dependencies like store, critic, breeder, and for injecting deterministic time and randomness for testing. Seed the engine with pre-built items and observe selection and outcome processing. ```typescript import { SemanticLoopEngine, InMemoryStore, HeuristicCritic, NoopBreeder, deriveEngagementScore, } from "@semantic-loop/core"; const store = new InMemoryStore(); const critic = new HeuristicCritic({ noveltyKeywords: ["counterintuitive", "framework", "moat"], penaltyKeywords: ["guaranteed", "viral"], }); // Inject deterministic time + randomness for testing const engine = new SemanticLoopEngine({ store, critic, breeder: new NoopBreeder(), config: { selection: { epsilon: 0, topKExplorationPool: 3, freshnessHalfLifeHours: 168, weights: { similarity: 0.45, scoreAvg: 0.35, exploration: 0.15, freshness: 0.05 } }, aggregation: { criticWeight: 0.6, engagementWeight: 0.4, decayFactor: 0.95 }, breeding: { scoreThreshold: 0.7, minAttempts: 1, maxChildrenPerBreed: 3, maxGeneration: 2, cooldownHours: 24 }, }, random: () => 0.99, // always greedy now: () => new Date("2025-01-15T12:00:00Z"), }); // Seed directly with pre-built SemanticItems (no embedding call) await engine.seed([ { id: "item-001", tribe: "founders", kind: "hook", content: "The moat is the loop that compounds.", embedding: [], metadata: {}, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }, ]); const selected = await engine.selectNext({ tribe: "founders" }); console.log(selected.strategy); // "greedy" console.log(selected.weightedScore); // 0.225 (exploration dominant, no history) const processed = await engine.ingestOutcome({ id: crypto.randomUUID(), itemId: "item-001", platform: "instagram", occurredAt: new Date().toISOString(), metrics: { views: 5000, likes: 200, shares: 50 }, engagementScore: deriveEngagementScore({ views: 5000, likes: 200, shares: 50 }), }); console.log(processed.finalScore); // 0.341 console.log(processed.aggregate.attempts); // 1 ``` -------------------------------- ### SelectOptions Interface Source: https://github.com/cemphlvn/semantic-loop/blob/main/docs/llms-full.txt Options for customizing the item selection process. ```APIDOC ## SelectOptions Interface Options to refine the selection of candidates from the Semantic Loop. ### Fields - **tribe** (string) - Optional - Filter by tribe. - **kind** (string) - Optional - Filter by item kind. - **limit** (number) - Optional - The maximum number of results to return. - **minSimilarity** (number) - Optional - The minimum similarity score for selected items. - **includeArchived** (boolean) - Optional - Whether to include archived items in the selection. Defaults to false. - **selection** (Partial) - Optional - Partial configuration for the selection strategy. ``` -------------------------------- ### SemanticLoopEngine Source: https://context7.com/cemphlvn/semantic-loop/llms.txt The stateless core orchestrator. Instantiate directly for full control over custom random, time injection for testing, and raw store/critic/breeder instances. ```APIDOC ## `SemanticLoopEngine` — low-level engine The stateless core orchestrator. `createLoop()` builds one internally, but you can instantiate it directly for full control: custom random, time injection for testing, raw store/critic/breeder instances. ```ts import { SemanticLoopEngine, InMemoryStore, HeuristicCritic, NoopBreeder, deriveEngagementScore, } from "@semantic-loop/core"; const store = new InMemoryStore(); const critic = new HeuristicCritic({ noveltyKeywords: ["counterintuitive", "framework", "moat"], penaltyKeywords: ["guaranteed", "viral"], }); // Inject deterministic time + randomness for testing const engine = new SemanticLoopEngine({ store, critic, breeder: new NoopBreeder(), config: { selection: { epsilon: 0, topKExplorationPool: 3, freshnessHalfLifeHours: 168, weights: { similarity: 0.45, scoreAvg: 0.35, exploration: 0.15, freshness: 0.05 } }, aggregation: { criticWeight: 0.6, engagementWeight: 0.4, decayFactor: 0.95 }, breeding: { scoreThreshold: 0.7, minAttempts: 1, maxChildrenPerBreed: 3, maxGeneration: 2, cooldownHours: 24 }, }, random: () => 0.99, // always greedy now: () => new Date("2025-01-15T12:00:00Z"), }); // Seed directly with pre-built SemanticItems (no embedding call) await engine.seed([ { id: "item-001", tribe: "founders", kind: "hook", content: "The moat is the loop that compounds.", embedding: [], metadata: {}, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }, ]); const selected = await engine.selectNext({ tribe: "founders" }); console.log(selected.strategy); // "greedy" console.log(selected.weightedScore); // 0.225 (exploration dominant, no history) const processed = await engine.ingestOutcome({ id: crypto.randomUUID(), itemId: "item-001", platform: "instagram", occurredAt: new Date().toISOString(), metrics: { views: 5000, likes: 200, shares: 50 }, engagementScore: deriveEngagementScore({ views: 5000, likes: 200, shares: 50 }), }); console.log(processed.finalScore); // 0.341 console.log(processed.aggregate.attempts); // 1 ``` ```