AI Services

← Services
STRVCT

Framework architecture for multi-provider AI integration, streaming execution, tool calling, and model-first operability.

Introduction & The Model-First AI Advantage

Strvct provides a comprehensive, multi-provider AI infrastructure built directly into the framework. Unlike traditional applications where AI integration requires writing bespoke API wrappers, per-screen tool specifications, and custom JSON serializers, Strvct's Naked Objects architecture makes the entire domain model natively AI-operable out of the box.

Because every domain class declares instance properties as slots with metadata annotations (slotType, canEditInspection, isSubnodeField), Strvct exposes a universal AI tool surface consisting of just two generic, constant-size functions:

  1. schema-fetch: Inspects slot metadata to generate JSON schemas for any domain class or live object instance.
  2. apply-patch: Validates and applies JSON patch payloads to mutate properties or update child relationships on live domain objects.
AI Agent / LLM Generates JSON patches Generic Tool Surface schema-fetch & apply-patch Strvct Annotation Bridge Slot metadata annotations UI Tile Updates Live view renders IndexedDB Pool Local persistence Sync Scheduler Deferred notifications

This tool surface remains constant in size whether an application contains 5 domain classes or 500. When an AI agent generates an invalid patch, the framework's rejected response returns the slot schema, enabling the LLM to self-correct in real time.

Service & Request Factory Architecture

AI providers are implemented as paired service and request singletons inheriting from base infrastructure classes:

  • SvAiService: High-level provider service singleton (e.g., SvAnthropicService, SvGeminiService, SvOpenAiService). Manages authentication, endpoint resolution, and model capability registries.
  • SvAiRequest: Low-level HTTP request wrapper handling message formatting, custom headers, and streaming chunk parsing.
SvAiService Base Provider Service SvAnthropicService Pairs with SvAnthropicRequest SvGeminiService Pairs with SvGeminiRequest SvOpenAiService Pairs with SvOpenAiRequest

Automatic Factory Resolution

SvAiService resolves its paired request class dynamically using naming conventions (SvGeminiService automatically pairs with SvGeminiRequest). Adding a new AI provider requires implementing the service and request subclass without registering explicit factory hooks.

Authentication & Token Flow

Authentication is resolved via apiKeyOrUserAuthToken():

  1. First checks SvCredentialManager for a Firebase bearer token (for production apps proxying requests through Firebase Cloud Functions to protect secrets).
  2. Falls back to a client-stored API key (for local development or direct user API key entry).

AI Model Registry (`SvAiChatModel`)

SvAiChatModel represents a specific LLM model instance (e.g., claude-3-5-sonnet, gemini-1.5-pro, gpt-4o). Each model definition includes:

  • modelName: Standard provider model identifier string.
  • inputTokenLimit / outputTokenLimit: Context window limits.
  • Capability Flags: supportsTemperature, supportsTopP, supportsImageGeneration, supportsVideoGeneration, supportsTools.

The global Services node provides global helper methods to query models across all registered providers:

const models = Services.shared().aiServices().chatModels();
const model  = Services.shared().aiServices().chatModelWithName("claude-3-5-sonnet");

Conversations & Messaging (`SvAiConversation` & `SvAiMessage`)

SvAiConversation manages conversational state, token counts, system prompts, tool call history, and active LLM chat requests.

  • SvAiMessage: Extends standard conversation messages with role designations (system, user, assistant).
  • Role Mapping: Provider services map generic role names to provider-specific conventions automatically (e.g., mapping assistant to model for Gemini APIs).

The Assistant ToolKit & Function Execution

Structured tool calling is coordinated by SvAssistantToolKit:

AI Response Stream <tool-call name="rollDice"> SvAssistantToolKit Function Dispatcher Streaming Execution Triggers audio & FX inline Completion State Patch Mutates live domain nodes

1. Tool Registration

Methods on model nodes are marked as toolable during slot setup:

const tool = this.methodNamed("rollDice");
tool.setDescription("Roll dice for a combat check");
tool.addParameter("notation", "String", "Standard dice notation like 2d6+3");
tool.setIsToolable(true);

2. Execution Timing Phases

Tools execute at specific points in the response lifecycle:

  • Streaming Phase (onStreamData): Executes in real time while tokens arrive (e.g., playing a sound effect or triggering a UI animation).
  • Completion Phase (onRequestComplete): Executes after the full response is validated (e.g., applying state mutations to domain nodes).
  • Narration Phase (onPlayback): Executes synchronized with Text-To-Speech (TTS) voice audio playback.

Incremental Streaming Response Parser (`SvAiParsedResponseMessage`)

AI responses arrive as continuous token streams. SvAiParsedResponseMessage parses structured XML tags incrementally during streaming without waiting for full response completion:

  • <tool-call>: Extracted and dispatched immediately to SvAssistantToolKit.
  • <narration>: Extracted and routed directly to the TTS voice audio queue for zero-latency speech synthesis.
  • <thought> / <quote> / <sentence>: Extracted for structured UI display in chat message views.

Modular Prompt Composition (`SvAiPromptComposer`)

SvAiPromptComposer builds complex system prompts dynamically using modular text template files without manual string concatenation in JavaScript:

[ Template File: SystemPrompt.txt ]
"System rules: {{file$Rules.txt}}
 Current Character: {{$characterSummary}}
 Available Actions: {{$tableOfContents}}"

Supported Substitution Directives:

  1. {{file$Path/ToFile.txt}}: Recursively embeds the contents of a secondary prompt template file.
  2. {{$methodName}}: Executes a getter method on the target domain object and inserts the string result.
  3. {{$tableOfContents}}: Generates a structured table of contents from headings in the prompt document.

Provider Support Matrix

Service ClassProviderKey Capabilities & Models
SvAnthropicServiceAnthropicClaude 3.5 Sonnet, Claude 3 Opus, native tool use
SvGeminiServiceGoogleGemini 1.5 Pro/Flash, text-to-video, multimodal inputs
SvOpenAiServiceOpenAIGPT-4o, DALL-E 3 image generation, TTS voice synthesis
SvGroqServiceGroqUltra-low-latency inference (OpenAI compatible)
SvDeepSeekServiceDeepSeekDeepSeek V3 / R1 reasoning models
SvXaiServicexAIGrok 2 models (OpenAI compatible)
SvImagineProServiceImagineProMidjourney image generation via proxy API

Adding a New AI Provider

To add a new AI provider, implement two classes following naming conventions:

  1. Service Subclass (SvNewProviderService.js): ```javascript (class SvNewProviderService extends SvAiService { modelsJson () { return [ { name: "new-model-v1", inputTokenLimit: 128000, outputTokenLimit: 4096 } ]; } }.initThisClass()); ```
  2. Request Subclass (SvNewProviderRequest.js): ```javascript (class SvNewProviderRequest extends SvAiRequest { buildBody () { // Format message payload for API endpoint } readDataChunk (chunk) { // Parse streaming SSE chunks } }.initThisClass()); ```
  3. Slot Registration: Declare the new service slot in Services.initPrototypeSlots(). The service/request factory automatically binds SvNewProviderService to SvNewProviderRequest.