🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@valv/core

Package Overview
Dependencies
Maintainers
2
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@valv/core

ORM + Access Control Layer for AI Agents

latest
Source
npmnpm
Version
0.10.0
Version published
Maintainers
2
Created
Source

@valv/core

The database-agnostic core of valv: the query grammar an LLM emits, the validator that checks it against your schema and policy, the policy injector, the shared SQL emitter, and the tool layer.

npm license

Most users install an adapter, not this package directly@valv/clickhouse or @valv/prisma wrap core with introspection and a dialect. See the root README for the full guide. Reach for @valv/core directly only to build a custom adapter.

What this package exports

AreaExports
OrchestrationValv (instantiated by adapters via createValv)
Query grammarQuerySchema; types Query, Expr, SelectItem
Write grammarInsertSchema, UpdateSchema, DeleteSchema; types Insert, Update, Delete, InjectedMutation
PolicyPolicyFn, PolicyResult, FieldPolicy, DefaultContext
Emissionemit, emitInsert/emitUpdate/emitDelete, the Dialect interface, BASE_FUNCTIONS, FnDef, ArgSpec
Output shaperesultSchema, ResultColumn
Tool formatsanthropic, openai, gemini formatters; NeutralTool, ToolToggle
Adapter contractValvAdapter, SchemaMap, CompiledQuery, BoundParam, MutationResult
ErrorsValidationError, PolicyViolationError; serializeResult

Building an adapter

Everything above the database is shared, so a new adapter is three methods plus a small dialect. The shared emit does clause assembly, parenthesisation, and parameter ordering — your dialect only says how to quote identifiers and render placeholders.

import type { ValvAdapter, SchemaMap, Query, CompiledQuery, FnDef, Dialect } from "@valv/core"
import { emit, BASE_FUNCTIONS } from "@valv/core"

const myDialect: Dialect = {
  quoteId: (id) => `"${id.replace(/"/g, '""')}"`,
  placeholder: (i) => `$${i + 1}`,
  // functions: { ...dialect-specific aggregates }
}

class MyAdapter implements ValvAdapter {
  async introspect(): Promise<SchemaMap> {
    // describe your tables → resources, fields (with coarse `type` + `nativeType`), relations
  }
  compile(query: Query, catalog: SchemaMap): CompiledQuery {
    return emit(query, catalog, myDialect)
  }
  async execute(sql: string, params?: unknown[]): Promise<unknown[]> {
    // run the parameterized statement, return rows
  }
  functions(): Record<string, FnDef> {
    return { ...BASE_FUNCTIONS, ...myDialect.functions }
  }
  // Optional — implement to support writes. The mutation is already validated
  // and policy-injected; emit it with emitInsert/emitUpdate/emitDelete and run it.
  // mutate?(m: InjectedMutation, catalog: SchemaMap): Promise<MutationResult>
}

Validation and policy injection never reach the adapter — security stays in core. A Dialect can also declare extra functions (FnDef: argument signature, return type, render), which become callable in the query grammar and are surfaced to the model through the query tool's enum. Writes are optional: implement mutate (the mutation arrives already validated and policy-injected) to opt in, or omit it for a read-only adapter.

Type-safe resource names

InferResources derives resource names from a typed client, so a misspelled policy key is a compile error:

import type { InferResources } from "@valv/core"
const valv = await createValv<typeof prisma, Ctx>(prisma)  // policy keys autocomplete

License

MIT

Keywords

ai agent

FAQs

Package last updated on 26 Jul 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts