{"_id":"@animastor/assistant","name":"@animastor/assistant","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@animastor/assistant","version":"0.1.0","description":"Animastor Assistant — the AI assistant contour of the Animastor backend, physically extracted from the host: chat engine (persona/system prompts, book context, mode tools, JSON patch pipeline with bundle-contract validation), the /api/v1/ai/* HTTP contour","keywords":["animastor","ai-assistant","chat","sse","llm"],"main":"src/index.cjs","exports":{".":"./src/index.cjs"},"scripts":{"test":"mocha --exit test/*.test.js"},"engines":{"node":">=18"},"license":"MIT","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/Animastor/animastor.git","directory":"packages/animastor-assistant"},"homepage":"https://github.com/Animastor/animastor/tree/main/packages/animastor-assistant#readme","bugs":{"url":"https://github.com/Animastor/animastor/issues"},"devDependencies":{"chai":"^6.2.2","mocha":"^11.7.5"},"_id":"@animastor/assistant@0.1.0","gitHead":"976cdf5e8900e1d616f08660fd51fc7420de5719","_nodeVersion":"22.22.3","_npmVersion":"10.9.8","dist":{"integrity":"sha512-xOCeN2hHVgvuLW/TzZ8AJlHagvefgpcKcBQaO7pJFbmj9BHIEqXIt5Z3MY+ysoHHYpPbAN6sl8DDDBM7c6tNCw==","shasum":"09e59b8db979d1ff2a70351f2204465c5b4cef57","tarball":"https://registry.npmjs.org/@animastor/assistant/-/assistant-0.1.0.tgz","fileCount":9,"unpackedSize":110490,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC/2EKKKP3sLaiVb/ZGlc1bQaL/acfJ9Ugii7qayUMURAIhAP5qjYWcnBiULEpuX0b2vQ6slKE4GwVzgZ+/mbQEo7Tb"}]},"_npmUser":{"name":"animastor","email":"admin@animastor.in"},"directories":{},"maintainers":[{"name":"animastor","email":"admin@animastor.in"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/assistant_0.1.0_1789097800957_0.42627311695357406"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-11T03:36:40.769Z","0.1.0":"2026-09-11T03:36:41.078Z","modified":"2026-09-11T03:36:42.027Z"},"maintainers":[{"name":"animastor","email":"admin@animastor.in"}],"description":"Animastor Assistant — the AI assistant contour of the Animastor backend, physically extracted from the host: chat engine (persona/system prompts, book context, mode tools, JSON patch pipeline with bundle-contract validation), the /api/v1/ai/* HTTP contour","homepage":"https://github.com/Animastor/animastor/tree/main/packages/animastor-assistant#readme","keywords":["animastor","ai-assistant","chat","sse","llm"],"repository":{"type":"git","url":"git+https://github.com/Animastor/animastor.git","directory":"packages/animastor-assistant"},"bugs":{"url":"https://github.com/Animastor/animastor/issues"},"license":"MIT","readme":"# @animastor/assistant\n\nThe AI assistant contour of the Animastor backend, packaged as a standalone,\nhost-agnostic module.\n\n## What this is\n\n`@animastor/assistant` owns the assistant logic and its HTTP contract:\n\n- **Chat engine** — persona/system prompt assembly, book-context builders\n  (full + compact), mode/topic prompts, the `edit_book` tool definition,\n  AI response parsing and the JSON-patch pipeline with bundle-contract\n  validation and a deterministic scene-participants normalizer.\n- **HTTP contour** — the `/api/v1/ai/*` surface: session CRUD, the\n  non-streaming chat route and the SSE stream route\n  (`meta` / `delta` / `done` / `error` frames), tool-call orchestration,\n  connector shared-inference and cloud-provider transports.\n- **Contracts** — the `AssistantPorts` seam and the chat-session repository\n  interface the host must implement.\n\nThe package is **pure logic + contracts**. It has **zero runtime\ndependencies**, does **not** touch the filesystem, does **not** read\n`process.env`, and imports nothing from the host. Every host capability\narrives through an injected dependency or port.\n\n## Requirements\n\n- Node.js >= 18\n\n## Installation\n\n```bash\nnpm install @animastor/assistant\n```\n\n## Public API\n\nThe package exposes a single root entrypoint — deep imports are blocked by\nthe `exports` map:\n\n```js\nconst {\n    createChatEngine,\n    createAssistantRoutes,\n    assertAssistantPorts,\n    assertSessionRepo,\n} = require('@animastor/assistant');\n```\n\n## Basic usage\n\n```js\nconst {\n    createChatEngine,\n    createAssistantRoutes,\n    assertAssistantPorts,\n} = require('@animastor/assistant');\nconst express = require('express');\n\n// 1. Build the engine with injected host dependencies.\nconst chatEngine = createChatEngine(config, {\n    // REQUIRED — host bundle-contract validator (object form).\n    validateBundleObject: (bundle) => ({ valid: true, errors: [] }),\n\n    // OPTIONAL — persona CONTENT (the host reads its own file and passes\n    // the resulting string; the package never sees the path or filesystem).\n    aiProfile: personaMarkdown,\n\n    // OPTIONAL — chat fallback provider base URL (operator config).\n    aiApiBaseUrl: process.env.AI_API_BASE_URL,\n});\n\n// 2. Build the host port adapter and validate it fail-fast.\nconst assistantPorts = assertAssistantPorts({\n    loadBook,           // (bookId) => book bundle | null\n    persistBook,        // (bookId, bundle) => void\n    validateBundle,     // (bundle) => { valid, errors }\n    validateBundleFile, // (name, data) => { valid, errors }\n    resolveChatAI,      // (bookId) => provider snapshot\n    sessionRepo,        // chat-session repository (see contract below)\n    purgeForBook,       // (bookId) => Promise<void>\n    chatTransport: {\n        safeFetch,          // SSRF-guarded fetch\n        runSharedInference, // connector / shared inference\n        describeSharedError,// (code) => string\n        chatAiSourceToken,  // (ai) => 'cloud' | 'system' | 'shared' | ...\n    },\n    log,                // host logger\n});\n\n// 3. Register the HTTP contour.\nconst app = express();\napp.use(express.json());\ncreateAssistantRoutes(app, redis, {\n    chatEngine,\n    assistantPorts,\n    utils: { log },\n});\n```\n\n## Required injected ports\n\n| Port | Purpose |\n|---|---|\n| `loadBook(bookId)` | Canonical-or-draft book read |\n| `persistBook(bookId, bundle)` | Book save (single semantics) |\n| `validateBundle(bundle)` | Bundle-contract validation |\n| `validateBundleFile(name, data)` | Per-file validation |\n| `resolveChatAI(bookId)` | Chat provider resolution |\n| `sessionRepo` | Chat-session persistence (see below) |\n| `purgeForBook(bookId)` | Assistant-data purge on book deletion |\n| `chatTransport.safeFetch` | SSRF-guarded outbound fetch |\n| `chatTransport.runSharedInference` | Connector/shared inference |\n| `chatTransport.describeSharedError` | Sanitized error text |\n| `chatTransport.chatAiSourceToken` | Safe consumer source token |\n| `log` | Host logger |\n\n`sessionRepo` must implement:\n`listSessionsForBook`, `getSession`, `getMessages`, `createSession`,\n`setMessages`, `renameSession`, `deleteSession`, `getBookIdForSession`,\n`purgeSessionsForBook` (validated by `assertSessionRepo`).\n\n## Architecture / dependency model\n\n```\nHost\n ├── provider adapter      ─┐\n ├── book adapter           │\n ├── session repository     ├── injected ports (AssistantPorts)\n ├── transport adapter      │\n └── AI profile loader     ─┘\n             ↓\n     @animastor/assistant\n             ↓\n        public API\n```\n\nDependency direction is **host → package**. The package never imports host\ncode; the host supplies concrete implementations at composition time. This\nkeeps storage, filesystem, provider and transport concerns on the host side.\n\n## Versioning / release\n\n- Current version: `0.1.0` (first publishable release; `npm pack` verified).\n- SemVer: the four public factories, the root-only export map, the\n  `AssistantPorts` shape and the `/api/v1/ai/*` HTTP/SSE contract are the\n  public contract — breaking any of them requires a major bump.\n- Publication is a manual, explicit step and is **not** automated in CI.\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-ed0c08a89690e5f16144ced7f0c724bb"}