Skip to content

@forinda/kickjs-ai

LLM providers, controller routes as model-callable tools, an agent loop, chat memory, and retrieval-augmented generation. The AI guide walks through each piece.

Installation

pnpm add @forinda/kickjs-ai

Optional peers: @anthropic-ai/sdk for AnthropicProvider, pg for PgVectorStore with a connection string, zod (or any schema library @forinda/kickjs-schema supports) for route and tool schemas.

Exports

Adapter and tokens

ExportDescription
AiAdapterAdapter factory: registers the provider, discovers tools, runs agent loops
AI_ADAPTERDI token for the adapter instance (AiAdapterInstance)
AI_PROVIDERDI token for the configured AiProvider
VECTOR_STOREDI token for a VectorStore you register
AI_TOOL_METADATAMetadata key @AiTool writes

Tools

ExportDescription
@AiTool(opts)Expose a controller method as a tool (description, name, inputSchema)
getAiToolMetaRead @AiTool options for a method
isAiToolWhether a method carries @AiTool

Providers

ExportDescription
OpenAIProviderOpenAI Chat Completions and embeddings, and OpenAI-compatible endpoints
AnthropicProviderClaude through @anthropic-ai/sdk; no embeddings
ProviderErrorError with the HTTP status and response body of a failed provider call

Prompts and memory

ExportDescription
createPrompt / Prompt templates (dotted paths resolve nested values)
InMemoryChatMemoryProcess-local conversation history
SlidingWindowChatMemoryWraps a memory with a message cap; pins the first system message

RAG

ExportDescription
RagServicenew RagService(provider, store): index, search, augmentChatInput
InMemoryVectorStoreBrute-force cosine search in memory
PgVectorStorePostgres + pgvector
QdrantVectorStoreQdrant over REST
PineconeVectorStorePinecone over REST
buildWhereClause, buildQdrantFilter, buildPineconeFilterFilter translators, exported for testing
cosineSimilarity, toPgVectorVector helpers

AiAdapter options

ts
interface AiAdapterOptions {
  provider: AiProvider
  /** Applied to every runAgent call; per-call values win. */
  defaults?: ChatOptions & { model?: string }
  /** Routes carrying these route flags become tools without @AiTool. */
  exposeWhen?: RouteFlagTest
  /** Routes carrying these route flags are never tools. */
  hideWhen?: RouteFlagTest
}

AiAdapterInstance

Inject with @Inject(AI_ADAPTER).

MethodDescription
runAgent(options)Chat → tool calls → dispatch → feedback until the model answers or maxSteps (default 8)
runAgentWithMemory(options)One agent turn with history loaded from and saved to a ChatMemory
getProvider(name?)A registered provider, or the default when name is omitted
registerProvider(name, p)Mount another provider under name (replaces an existing one with that name)
unregisterProvider(name)Unmount a provider; the default can't be removed
getTools()Discovered tool definitions
setServerBaseUrl(url)Send tool calls to a URL over HTTP instead of through the app (tests driving hooks by hand)

RunAgentOptions adds messages, provider (a registered name or an instance), model, tools ('auto' or a list), maxSteps, headers (sent with every tool call) and signal to ChatOptions. RunAgentResult has content, messages, steps, usage, maxStepsReached, finishReason and refusal.

Chat types

TypeKey fields
ChatMessagerole, content, toolCalls, toolCallId, isError, providerContent
ChatOptionstemperature, topP, maxTokens, stopSequences, effort, signal
ChatResponsecontent, toolCalls, usage, finishReason (stop / length / tool_call / content_filter), refusal, providerContent
ChatChunkcontent, toolCallDelta (id, index, name, argumentsDelta), done; final chunk finishReason, usage
ChatUsagepromptTokens, completionTokens, totalTokens, cacheReadTokens, cacheWriteTokens
AiProvidername, chat, stream, embed — implement it for a custom provider

Released under the MIT License. Built with TypeScript — runs on Express, Fastify, or h3.