@terreno/mcp 0.31.0 → 56.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +15 -16
- package/dist/bootstrap.js.map +1 -1
- package/dist/docs/templates/bootstrap/backend/types/models/userTypes.template.md +4 -5
- package/dist/docs/templates/bootstrap/frontend/app/_layout.template.tsx +1 -1
- package/dist/docs/templates/tools/model.template.md +2 -4
- package/dist/docs/versioned/next/README.md +1 -0
- package/dist/docs/versioned/next/explanation/README.md +1 -7
- package/dist/docs/versioned/next/how-to/README.md +2 -8
- package/dist/docs/versioned/next/how-to/deploy-to-gcp.md +228 -20
- package/dist/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +445 -0
- package/dist/docs/versioned/next/implementationPlans/PLAN_INDEX.md +4 -57
- package/dist/docs/versioned/next/implementationPlans/README.md +30 -56
- package/dist/docs/versioned/next/implementationPlans/agentic-sdlc-plugin.md +1 -2
- package/dist/docs/versioned/next/implementationPlans/ai-dev-loop-boost.md +0 -1
- package/dist/docs/versioned/next/implementationPlans/build-terreno-app-validation.md +0 -1
- package/dist/docs/versioned/next/implementationPlans/deploy-to-gcp.md +0 -1
- package/dist/docs/versioned/next/implementationPlans/deploy-to-vercel.md +0 -1
- package/dist/docs/versioned/next/implementationPlans/deployment-foundation.md +0 -1
- package/dist/docs/versioned/next/implementationPlans/docs-reference-coverage.md +0 -1
- package/dist/docs/versioned/next/implementationPlans/docs-tutorials-ai-first.md +0 -1
- package/dist/docs/versioned/next/implementationPlans/examples-demo-coverage.md +0 -1
- package/dist/docs/versioned/next/implementationPlans/oss-governance-baseline.md +0 -1
- package/dist/docs/versioned/next/implementationPlans/positioning-django-rails-universal.md +0 -1
- package/dist/docs/versioned/next/implementationPlans/public-roadmap-github.md +0 -1
- package/dist/docs/versioned/next/implementationPlans/rtk-to-syncdb-migration-docs.md +52 -47
- package/dist/docs/versioned/next/implementationPlans/syncdb-api-inventory.md +303 -0
- package/dist/docs/versioned/next/implementationPlans/syncdb-codegen.md +252 -0
- package/dist/docs/versioned/next/implementationPlans/syncdb-local-first.md +468 -420
- package/dist/docs/versioned/next/implementationPlans/syncdb-phase-c-design.md +425 -0
- package/dist/docs/versioned/next/implementationPlans/terreno-syncdb-2.md +800 -0
- package/dist/docs/versioned/next/implementationPlans/upgrade-guides-and-skill.md +0 -1
- package/dist/docs/versioned/next/implementationPlans/web-ssr-and-admin-spa.md +0 -1
- package/dist/docs/versioned/next/reference/README.md +1 -4
- package/dist/docs/versioned/next/reference/environment-variables.md +382 -220
- package/dist/docs/versioned/next/reference/syncdb.md +456 -0
- package/dist/docs/versioned/next/superpowers/plans/2026-07-28-admin-mobile-navigation.md +97 -0
- package/dist/docs/versioned/next/superpowers/specs/2026-07-28-admin-mobile-navigation-design.md +36 -0
- package/dist/docs/versioned/next/tasks/agentic-sdlc-plugin.md +5 -5
- package/dist/docs/versioned/next/tasks/deploy-to-gcp.md +11 -11
- package/dist/docs/versioned/next/tasks/deployment-foundation.md +12 -12
- package/dist/docs/versioned/next/tasks/docs-reference-coverage.md +4 -4
- package/dist/docs/versioned/next/tasks/oss-governance-baseline.md +18 -18
- package/dist/docs/versioned/next/tasks/positioning-django-rails-universal.md +4 -4
- package/dist/docs/versioned/next/tasks/public-roadmap-github.md +15 -15
- package/dist/docs/versioned/next/tasks/rtk-to-syncdb-migration-docs.md +10 -10
- package/dist/docs/versioned/next/tasks/syncdb-codegen.md +65 -0
- package/dist/docs/versioned/next/tasks/syncdb-local-first.md +434 -117
- package/package.json +4 -5
- package/src/docs/templates/bootstrap/backend/types/models/userTypes.template.md +4 -5
- package/src/docs/templates/bootstrap/frontend/app/_layout.template.tsx +1 -1
- package/src/docs/templates/tools/model.template.md +2 -4
- package/src/docs/versioned/next/README.md +1 -0
- package/src/docs/versioned/next/explanation/README.md +1 -7
- package/src/docs/versioned/next/how-to/README.md +2 -8
- package/src/docs/versioned/next/how-to/deploy-to-gcp.md +228 -20
- package/src/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +445 -0
- package/src/docs/versioned/next/implementationPlans/PLAN_INDEX.md +4 -57
- package/src/docs/versioned/next/implementationPlans/README.md +30 -56
- package/src/docs/versioned/next/implementationPlans/agentic-sdlc-plugin.md +1 -2
- package/src/docs/versioned/next/implementationPlans/ai-dev-loop-boost.md +0 -1
- package/src/docs/versioned/next/implementationPlans/build-terreno-app-validation.md +0 -1
- package/src/docs/versioned/next/implementationPlans/deploy-to-gcp.md +0 -1
- package/src/docs/versioned/next/implementationPlans/deploy-to-vercel.md +0 -1
- package/src/docs/versioned/next/implementationPlans/deployment-foundation.md +0 -1
- package/src/docs/versioned/next/implementationPlans/docs-reference-coverage.md +0 -1
- package/src/docs/versioned/next/implementationPlans/docs-tutorials-ai-first.md +0 -1
- package/src/docs/versioned/next/implementationPlans/examples-demo-coverage.md +0 -1
- package/src/docs/versioned/next/implementationPlans/oss-governance-baseline.md +0 -1
- package/src/docs/versioned/next/implementationPlans/positioning-django-rails-universal.md +0 -1
- package/src/docs/versioned/next/implementationPlans/public-roadmap-github.md +0 -1
- package/src/docs/versioned/next/implementationPlans/rtk-to-syncdb-migration-docs.md +52 -47
- package/src/docs/versioned/next/implementationPlans/syncdb-api-inventory.md +303 -0
- package/src/docs/versioned/next/implementationPlans/syncdb-codegen.md +252 -0
- package/src/docs/versioned/next/implementationPlans/syncdb-local-first.md +468 -420
- package/src/docs/versioned/next/implementationPlans/syncdb-phase-c-design.md +425 -0
- package/src/docs/versioned/next/implementationPlans/terreno-syncdb-2.md +800 -0
- package/src/docs/versioned/next/implementationPlans/upgrade-guides-and-skill.md +0 -1
- package/src/docs/versioned/next/implementationPlans/web-ssr-and-admin-spa.md +0 -1
- package/src/docs/versioned/next/reference/README.md +1 -4
- package/src/docs/versioned/next/reference/environment-variables.md +382 -220
- package/src/docs/versioned/next/reference/syncdb.md +456 -0
- package/src/docs/versioned/next/superpowers/plans/2026-07-28-admin-mobile-navigation.md +97 -0
- package/src/docs/versioned/next/superpowers/specs/2026-07-28-admin-mobile-navigation-design.md +36 -0
- package/src/docs/versioned/next/tasks/agentic-sdlc-plugin.md +5 -5
- package/src/docs/versioned/next/tasks/deploy-to-gcp.md +11 -11
- package/src/docs/versioned/next/tasks/deployment-foundation.md +12 -12
- package/src/docs/versioned/next/tasks/docs-reference-coverage.md +4 -4
- package/src/docs/versioned/next/tasks/oss-governance-baseline.md +18 -18
- package/src/docs/versioned/next/tasks/positioning-django-rails-universal.md +4 -4
- package/src/docs/versioned/next/tasks/public-roadmap-github.md +15 -15
- package/src/docs/versioned/next/tasks/rtk-to-syncdb-migration-docs.md +10 -10
- package/src/docs/versioned/next/tasks/syncdb-codegen.md +65 -0
- package/src/docs/versioned/next/tasks/syncdb-local-first.md +434 -117
- package/LICENSE +0 -21
- package/dist/__tests__/bootstrap.test.d.ts +0 -2
- package/dist/__tests__/bootstrap.test.d.ts.map +0 -1
- package/dist/__tests__/bootstrap.test.js +0 -299
- package/dist/__tests__/bootstrap.test.js.map +0 -1
- package/dist/__tests__/databaseQuery.test.d.ts +0 -2
- package/dist/__tests__/databaseQuery.test.d.ts.map +0 -1
- package/dist/__tests__/databaseQuery.test.js +0 -83
- package/dist/__tests__/databaseQuery.test.js.map +0 -1
- package/dist/__tests__/docsRoot.test.d.ts +0 -2
- package/dist/__tests__/docsRoot.test.d.ts.map +0 -1
- package/dist/__tests__/docsRoot.test.js +0 -59
- package/dist/__tests__/docsRoot.test.js.map +0 -1
- package/dist/__tests__/inferPackages.test.d.ts +0 -2
- package/dist/__tests__/inferPackages.test.d.ts.map +0 -1
- package/dist/__tests__/inferPackages.test.js +0 -35
- package/dist/__tests__/inferPackages.test.js.map +0 -1
- package/dist/__tests__/preload.d.ts +0 -2
- package/dist/__tests__/preload.d.ts.map +0 -1
- package/dist/__tests__/preload.js +0 -12
- package/dist/__tests__/preload.js.map +0 -1
- package/dist/__tests__/prompts.test.d.ts +0 -2
- package/dist/__tests__/prompts.test.d.ts.map +0 -1
- package/dist/__tests__/prompts.test.js +0 -295
- package/dist/__tests__/prompts.test.js.map +0 -1
- package/dist/__tests__/resources.test.d.ts +0 -2
- package/dist/__tests__/resources.test.d.ts.map +0 -1
- package/dist/__tests__/resources.test.js +0 -352
- package/dist/__tests__/resources.test.js.map +0 -1
- package/dist/__tests__/search.test.d.ts +0 -2
- package/dist/__tests__/search.test.d.ts.map +0 -1
- package/dist/__tests__/search.test.js +0 -163
- package/dist/__tests__/search.test.js.map +0 -1
- package/dist/__tests__/tools.test.d.ts +0 -2
- package/dist/__tests__/tools.test.d.ts.map +0 -1
- package/dist/__tests__/tools.test.js +0 -540
- package/dist/__tests__/tools.test.js.map +0 -1
- package/dist/__tests__/upgradeGuide.test.d.ts +0 -2
- package/dist/__tests__/upgradeGuide.test.d.ts.map +0 -1
- package/dist/__tests__/upgradeGuide.test.js +0 -22
- package/dist/__tests__/upgradeGuide.test.js.map +0 -1
- package/dist/docs/upgrades/0.31.0.md +0 -60
- package/dist/docs/versioned/next/explanation/deployment-architecture-gcp.md +0 -65
- package/dist/docs/versioned/next/explanation/deployment-baseline.md +0 -78
- package/dist/docs/versioned/next/explanation/positioning.md +0 -164
- package/dist/docs/versioned/next/explanation/repository-settings.md +0 -44
- package/dist/docs/versioned/next/explanation/roadmap-process.md +0 -330
- package/dist/docs/versioned/next/explanation/roadmap-seed-issues.md +0 -866
- package/dist/docs/versioned/next/how-to/build-for-web.md +0 -69
- package/dist/docs/versioned/next/how-to/deploy-backend-to-cloud-run.md +0 -115
- package/dist/docs/versioned/next/how-to/deploy-web-to-gcs-cdn.md +0 -183
- package/dist/docs/versioned/next/implementationPlans/b2b-platform-program.md +0 -114
- package/dist/docs/versioned/next/implementationPlans/billing-stripe.md +0 -158
- package/dist/docs/versioned/next/implementationPlans/comms-abstraction.md +0 -240
- package/dist/docs/versioned/next/implementationPlans/comms-adapter-expo-push.md +0 -107
- package/dist/docs/versioned/next/implementationPlans/comms-adapter-sendgrid.md +0 -107
- package/dist/docs/versioned/next/implementationPlans/comms-adapter-twilio-sms.md +0 -102
- package/dist/docs/versioned/next/implementationPlans/comms-adapter-twilio-verify.md +0 -93
- package/dist/docs/versioned/next/implementationPlans/infra-mcp-research.md +0 -188
- package/dist/docs/versioned/next/implementationPlans/infra-mcp.md +0 -269
- package/dist/docs/versioned/next/implementationPlans/native-module-baseline.md +0 -105
- package/dist/docs/versioned/next/implementationPlans/orgs-and-teams.md +0 -158
- package/dist/docs/versioned/next/implementationPlans/password-reset-and-email-verification.md +0 -147
- package/dist/docs/versioned/next/reference/admin-spa.md +0 -130
- package/dist/docs/versioned/next/reference/ai.md +0 -519
- package/dist/docs/versioned/next/reference/test.md +0 -108
- package/dist/docs/versioned/next/roadmap.md +0 -9
- package/dist/docs/versioned/next/tasks/README.md +0 -42
- package/dist/docs/versioned/next/tasks/billing-stripe.md +0 -75
- package/dist/docs/versioned/next/tasks/comms-abstraction.md +0 -77
- package/dist/docs/versioned/next/tasks/comms-adapter-expo-push.md +0 -29
- package/dist/docs/versioned/next/tasks/comms-adapter-sendgrid.md +0 -29
- package/dist/docs/versioned/next/tasks/comms-adapter-twilio-sms.md +0 -29
- package/dist/docs/versioned/next/tasks/comms-adapter-twilio-verify.md +0 -19
- package/dist/docs/versioned/next/tasks/infra-mcp.md +0 -43
- package/dist/docs/versioned/next/tasks/native-module-baseline.md +0 -42
- package/dist/docs/versioned/next/tasks/orgs-and-teams.md +0 -70
- package/dist/docs/versioned/next/tasks/password-reset-and-email-verification.md +0 -60
- package/src/docs/upgrades/0.31.0.md +0 -60
- package/src/docs/versioned/next/explanation/deployment-architecture-gcp.md +0 -65
- package/src/docs/versioned/next/explanation/deployment-baseline.md +0 -78
- package/src/docs/versioned/next/explanation/positioning.md +0 -164
- package/src/docs/versioned/next/explanation/repository-settings.md +0 -44
- package/src/docs/versioned/next/explanation/roadmap-process.md +0 -330
- package/src/docs/versioned/next/explanation/roadmap-seed-issues.md +0 -866
- package/src/docs/versioned/next/how-to/build-for-web.md +0 -69
- package/src/docs/versioned/next/how-to/deploy-backend-to-cloud-run.md +0 -115
- package/src/docs/versioned/next/how-to/deploy-web-to-gcs-cdn.md +0 -183
- package/src/docs/versioned/next/implementationPlans/b2b-platform-program.md +0 -114
- package/src/docs/versioned/next/implementationPlans/billing-stripe.md +0 -158
- package/src/docs/versioned/next/implementationPlans/comms-abstraction.md +0 -240
- package/src/docs/versioned/next/implementationPlans/comms-adapter-expo-push.md +0 -107
- package/src/docs/versioned/next/implementationPlans/comms-adapter-sendgrid.md +0 -107
- package/src/docs/versioned/next/implementationPlans/comms-adapter-twilio-sms.md +0 -102
- package/src/docs/versioned/next/implementationPlans/comms-adapter-twilio-verify.md +0 -93
- package/src/docs/versioned/next/implementationPlans/infra-mcp-research.md +0 -188
- package/src/docs/versioned/next/implementationPlans/infra-mcp.md +0 -269
- package/src/docs/versioned/next/implementationPlans/native-module-baseline.md +0 -105
- package/src/docs/versioned/next/implementationPlans/orgs-and-teams.md +0 -158
- package/src/docs/versioned/next/implementationPlans/password-reset-and-email-verification.md +0 -147
- package/src/docs/versioned/next/reference/admin-spa.md +0 -130
- package/src/docs/versioned/next/reference/ai.md +0 -519
- package/src/docs/versioned/next/reference/test.md +0 -108
- package/src/docs/versioned/next/roadmap.md +0 -9
- package/src/docs/versioned/next/tasks/README.md +0 -42
- package/src/docs/versioned/next/tasks/billing-stripe.md +0 -75
- package/src/docs/versioned/next/tasks/comms-abstraction.md +0 -77
- package/src/docs/versioned/next/tasks/comms-adapter-expo-push.md +0 -29
- package/src/docs/versioned/next/tasks/comms-adapter-sendgrid.md +0 -29
- package/src/docs/versioned/next/tasks/comms-adapter-twilio-sms.md +0 -29
- package/src/docs/versioned/next/tasks/comms-adapter-twilio-verify.md +0 -19
- package/src/docs/versioned/next/tasks/infra-mcp.md +0 -43
- package/src/docs/versioned/next/tasks/native-module-baseline.md +0 -42
- package/src/docs/versioned/next/tasks/orgs-and-teams.md +0 -70
- package/src/docs/versioned/next/tasks/password-reset-and-email-verification.md +0 -60
|
@@ -1,519 +0,0 @@
|
|
|
1
|
-
# @terreno/ai
|
|
2
|
-
|
|
3
|
-
AI service layer for Terreno backends: provider-agnostic chat via the Vercel AI SDK, request logging, GPT history, projects, file uploads, MCP tools, and optional Langfuse integration.
|
|
4
|
-
|
|
5
|
-
## Table of Contents
|
|
6
|
-
|
|
7
|
-
- [Install](#install)
|
|
8
|
-
- [Commands](#commands)
|
|
9
|
-
- [Architecture](#architecture)
|
|
10
|
-
- [Key exports](#key-exports)
|
|
11
|
-
- [AIService](#aiservice)
|
|
12
|
-
- [Structured JSON output](#structured-json-output)
|
|
13
|
-
- [TemperaturePresets](#temperaturepresets)
|
|
14
|
-
- [Models](#models)
|
|
15
|
-
- [Route registrars](#route-registrars)
|
|
16
|
-
- [AiApp plugin](#aiapp-plugin)
|
|
17
|
-
- [LangfuseApp plugin](#langfuseapp-plugin)
|
|
18
|
-
- [Langfuse integration](#langfuse-integration)
|
|
19
|
-
- [FileStorageService](#filestorageservice)
|
|
20
|
-
- [MCPService](#mcpservice)
|
|
21
|
-
- [Gemini and Vertex helpers](#gemini-and-vertex-helpers)
|
|
22
|
-
- [Web search types](#web-search-types)
|
|
23
|
-
- [Integration example](#integration-example)
|
|
24
|
-
- [Environment variables](#environment-variables)
|
|
25
|
-
- [Conventions](#conventions)
|
|
26
|
-
- [Testing](#testing)
|
|
27
|
-
|
|
28
|
-
## Install
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
bun add @terreno/ai @terreno/api mongoose
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
Peer dependencies: `@terreno/api`, `mongoose` (^8.0.0). Consuming apps also install a Vercel AI SDK provider (e.g. `@ai-sdk/google`) for their chosen model.
|
|
35
|
-
|
|
36
|
-
## Commands
|
|
37
|
-
|
|
38
|
-
From the `@terreno/ai` package directory:
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
bun run compile # Compile TypeScript
|
|
42
|
-
bun run dev # Watch mode (tsc -w)
|
|
43
|
-
bun run test # Run tests (with bunSetup preload)
|
|
44
|
-
bun run lint # Lint code
|
|
45
|
-
bun run lint:fix # Fix lint issues
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Architecture
|
|
49
|
-
|
|
50
|
-
```
|
|
51
|
-
src/
|
|
52
|
-
index.ts # Public exports
|
|
53
|
-
aiApp.ts # AiApp TerrenoPlugin
|
|
54
|
-
langfuseApp.ts # LangfuseApp TerrenoPlugin
|
|
55
|
-
langfuseClient.ts # Langfuse SDK client lifecycle
|
|
56
|
-
langfuseCache.ts # Prompt/trace caching
|
|
57
|
-
langfusePrompts.ts # Prompt compile/fetch helpers
|
|
58
|
-
langfuseTracing.ts # OpenTelemetry tracing setup
|
|
59
|
-
langfuseVercelAi.ts # Bridge Langfuse prompts to Vercel AI SDK
|
|
60
|
-
models/
|
|
61
|
-
aiRequest.ts # AI request logging model
|
|
62
|
-
gptHistory.ts # Conversation history model
|
|
63
|
-
fileAttachment.ts # Uploaded file metadata
|
|
64
|
-
project.ts # GPT project + memories
|
|
65
|
-
routes/
|
|
66
|
-
gpt.ts # Streaming chat, remix, tools, ratings
|
|
67
|
-
gptHistories.ts # History CRUD
|
|
68
|
-
aiRequestsExplorer.ts # Admin request explorer
|
|
69
|
-
files.ts # File upload/signed URL/delete
|
|
70
|
-
projects.ts # Project CRUD + memories
|
|
71
|
-
mcp.ts # MCP server status and tools
|
|
72
|
-
service/
|
|
73
|
-
aiService.ts # Provider-agnostic AI service
|
|
74
|
-
fileStorage.ts # GCS upload helper
|
|
75
|
-
mcpService.ts # MCP client connections
|
|
76
|
-
parseAiJson.ts # LLM JSON normalization/parsing
|
|
77
|
-
prompts.ts # System prompt constants
|
|
78
|
-
gemini.ts # Gemini Developer API model listing
|
|
79
|
-
vertex.ts # Vertex AI provider helpers
|
|
80
|
-
webSearchTool.ts # WebSearchProvider interface
|
|
81
|
-
types/ # Shared TypeScript types
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## Key exports
|
|
85
|
-
|
|
86
|
-
- **Plugins:** `AiApp`, `LangfuseApp`
|
|
87
|
-
- **Service:** `AIService`, `TemperaturePresets`, `FileStorageService`, `MCPService`
|
|
88
|
-
- **Models:** `AIRequest`, `GptHistory`, `FileAttachment`, `Project`
|
|
89
|
-
- **Routes:** `addGptRoutes`, `addGptHistoryRoutes`, `addAiRequestsExplorerRoutes`, `addFileRoutes`, `addProjectRoutes`, `addMcpRoutes`
|
|
90
|
-
- **Structured output:** `parseAiJson`, `normalizeLlmJsonTextForStructuredOutput`, re-exported `Output`, `jsonSchema`, `JSONValue`, `FlexibleSchema` from `ai`
|
|
91
|
-
- **Langfuse:** `initLangfuseClient`, `getLangfuseClient`, `shutdownLangfuseClient`, `compilePrompt`, `createPrompt`, `getPrompt`, `createTelemetryConfig`, `preparePromptForAI`, `initTracing`, `shutdownTracing`, `LangfuseCache`, cache helpers
|
|
92
|
-
- **Gemini / Vertex:** `listGeminiApiModels`, `normalizeGeminiModelId`, `GEMINI_API_BASE_URL`, `createVertexProvider`, `listEnabledVertexModels`, `verifyVertexModelsEnabled`, `assertVertexModelsEnabled`, `isVertexModelAllowed`, `normalizeVertexModelId`, `DEFAULT_VERTEX_LOCATION`
|
|
93
|
-
- **Prompts:** `CONTENT_SUMMARY_PROMPT`, `DEFAULT_GPT_MEMORY`, `JSON_VALUE_SYSTEM_PROMPT`, `REMIX_PROMPT`, `TITLE_GENERATION_PROMPT`, `TRANSLATION_PROMPT`
|
|
94
|
-
- **Web search:** `WebSearchProvider`, `WebSearchResult` types
|
|
95
|
-
|
|
96
|
-
## AIService
|
|
97
|
-
|
|
98
|
-
Provider-agnostic wrapper around a Vercel AI SDK `LanguageModel`. The consuming app supplies the model instance.
|
|
99
|
-
|
|
100
|
-
```typescript
|
|
101
|
-
import {AIService} from "@terreno/ai";
|
|
102
|
-
import {google} from "@ai-sdk/google";
|
|
103
|
-
|
|
104
|
-
const aiService = new AIService({
|
|
105
|
-
model: google("gemini-2.5-flash"),
|
|
106
|
-
defaultTemperature: 1.0,
|
|
107
|
-
});
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### Constructor options
|
|
111
|
-
|
|
112
|
-
| Option | Description |
|
|
113
|
-
|--------|-------------|
|
|
114
|
-
| `model` | Vercel AI SDK `LanguageModel` instance (required) |
|
|
115
|
-
| `defaultTemperature` | Default temperature for text/stream calls (default: `TemperaturePresets.DEFAULT`) |
|
|
116
|
-
|
|
117
|
-
### Properties
|
|
118
|
-
|
|
119
|
-
| Property | Description |
|
|
120
|
-
|----------|-------------|
|
|
121
|
-
| `model` | Configured `LanguageModel` |
|
|
122
|
-
| `defaultTemperature` | Default temperature |
|
|
123
|
-
| `modelId` | Resolved model identifier string |
|
|
124
|
-
|
|
125
|
-
### Methods
|
|
126
|
-
|
|
127
|
-
| Method | Description |
|
|
128
|
-
|--------|-------------|
|
|
129
|
-
| `generateText(options)` | Non-streaming text generation; logs as `requestType: "general"` |
|
|
130
|
-
| `generateJsonValue(options)` | Any JSON value via `Output.json()`; logs as `"json_value"` |
|
|
131
|
-
| `generateJsonObject(options)` | Typed object from schema/Zod via `Output.object()`; logs as `"json_object"` |
|
|
132
|
-
| `generateJsonArray(options)` | Typed array via `Output.array()`; logs as `"json_array"` |
|
|
133
|
-
| `generateTextStream(options)` | Async generator of text chunks; logs full response after stream completes |
|
|
134
|
-
| `generateRemix(options)` | Reword text using `REMIX_PROMPT` at `TemperaturePresets.BALANCED` |
|
|
135
|
-
| `generateSummary(options)` | Summarize text using `CONTENT_SUMMARY_PROMPT` at `TemperaturePresets.LOW` |
|
|
136
|
-
| `translateText(options)` | Translate text using `TRANSLATION_PROMPT` at `TemperaturePresets.LOW` |
|
|
137
|
-
| `buildMessages(prompts)` | Convert `GptHistoryPrompt[]` to Vercel AI SDK `ModelMessage[]` (skips tool-call/result entries) |
|
|
138
|
-
| `generateChatStream(options)` | Stream multi-turn chat with optional tools; logs prompt as joined message text |
|
|
139
|
-
|
|
140
|
-
All generation methods log to `AIRequest` via private `logRequest()`. Logging failures never throw.
|
|
141
|
-
|
|
142
|
-
## Structured JSON output
|
|
143
|
-
|
|
144
|
-
`generateJsonValue`, `generateJsonObject`, and `generateJsonArray`:
|
|
145
|
-
|
|
146
|
-
- Default to `TemperaturePresets.DETERMINISTIC` when `temperature` is omitted.
|
|
147
|
-
- Use `JSON_VALUE_SYSTEM_PROMPT` when `systemPrompt` is omitted.
|
|
148
|
-
- Run model text through `normalizeLlmJsonTextForStructuredOutput` before Vercel `Output.*` parsing (strips fences, preamble, balanced JSON slice, trailing commas, smart-quote repair).
|
|
149
|
-
- On failure: `logger.error` records prompt, system prompt, raw model text, and error details; `AIRequest` stores `response` (raw text or sentinel), `error`, and `metadata` (`system`, `finishReason`, `errorStack`, `rawModelTextCaptured`).
|
|
150
|
-
|
|
151
|
-
Standalone helpers:
|
|
152
|
-
|
|
153
|
-
```typescript
|
|
154
|
-
import {parseAiJson, normalizeLlmJsonTextForStructuredOutput} from "@terreno/ai";
|
|
155
|
-
|
|
156
|
-
const result = parseAiJson<MyType>(rawLlmText);
|
|
157
|
-
if (result.success) {
|
|
158
|
-
console.info(result.data);
|
|
159
|
-
}
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
Re-exported from `ai` for schema building: `Output`, `jsonSchema`, types `JSONValue`, `FlexibleSchema`.
|
|
163
|
-
|
|
164
|
-
## TemperaturePresets
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
import {TemperaturePresets} from "@terreno/ai";
|
|
168
|
-
|
|
169
|
-
TemperaturePresets.DETERMINISTIC // 0
|
|
170
|
-
TemperaturePresets.LOW // 0.3
|
|
171
|
-
TemperaturePresets.BALANCED // 0.7
|
|
172
|
-
TemperaturePresets.DEFAULT // 1.0
|
|
173
|
-
TemperaturePresets.HIGH // 1.5
|
|
174
|
-
TemperaturePresets.MAXIMUM // 2.0
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
## Models
|
|
178
|
-
|
|
179
|
-
### AIRequest
|
|
180
|
-
|
|
181
|
-
Logs all AI calls for monitoring and admin explorer.
|
|
182
|
-
|
|
183
|
-
| Field | Type | Description |
|
|
184
|
-
|-------|------|-------------|
|
|
185
|
-
| `aiModel` | string | Model identifier (field name avoids Mongoose `model` conflict) |
|
|
186
|
-
| `prompt` | string | Input prompt |
|
|
187
|
-
| `requestType` | string | e.g. `general`, `remix`, `summarization`, `translation`, `json_value`, `json_object`, `json_array` |
|
|
188
|
-
| `response` | string? | Response text |
|
|
189
|
-
| `responseTime` | number? | Milliseconds |
|
|
190
|
-
| `tokensUsed` | number? | Total tokens |
|
|
191
|
-
| `userId` | ObjectId? | Requesting user |
|
|
192
|
-
| `error` | string? | Error message |
|
|
193
|
-
| `metadata` | Mixed? | Extra data (e.g. structured-output debug) |
|
|
194
|
-
| `parentRequestId` | ObjectId? | Parent in multi-agent workflow |
|
|
195
|
-
| `subRequestIds` | ObjectId[]? | Child request refs |
|
|
196
|
-
| `totalResponseTime` | number? | Combined sub-request time |
|
|
197
|
-
| `totalTokensUsed` | number? | Combined sub-request tokens |
|
|
198
|
-
|
|
199
|
-
**Statics:** `AIRequest.logRequest(params)`, `AIRequest.logMultiAgentRequest(params)`
|
|
200
|
-
|
|
201
|
-
**Plugins:** `createdUpdatedPlugin`, `isDeletedPlugin`, `findOneOrNone`, `findExactlyOne`
|
|
202
|
-
|
|
203
|
-
### GptHistory
|
|
204
|
-
|
|
205
|
-
Conversation history with multi-modal prompts.
|
|
206
|
-
|
|
207
|
-
| Field | Type | Description |
|
|
208
|
-
|-------|------|-------------|
|
|
209
|
-
| `userId` | ObjectId | Owner (required) |
|
|
210
|
-
| `title` | string? | Auto-generated on first `/gpt/prompt` response when empty |
|
|
211
|
-
| `projectId` | ObjectId? | Optional project association |
|
|
212
|
-
| `prompts` | array | Messages: `text`, `type` (`user` \| `assistant` \| `system` \| `tool-call` \| `tool-result`), optional `content` parts, `model`, `rating`, tool fields |
|
|
213
|
-
|
|
214
|
-
**Virtual:** `ownerId` aliases `userId` for `Permissions.IsOwner`.
|
|
215
|
-
|
|
216
|
-
### FileAttachment
|
|
217
|
-
|
|
218
|
-
Metadata for files stored in GCS.
|
|
219
|
-
|
|
220
|
-
| Field | Type | Description |
|
|
221
|
-
|-------|------|-------------|
|
|
222
|
-
| `userId` | ObjectId | Uploader |
|
|
223
|
-
| `filename` | string | Original filename |
|
|
224
|
-
| `gcsKey` | string | Unique GCS object key |
|
|
225
|
-
| `mimeType` | string | MIME type |
|
|
226
|
-
| `size` | number | Bytes |
|
|
227
|
-
| `url` | string | Public GCS URL |
|
|
228
|
-
|
|
229
|
-
**Virtual:** `ownerId` aliases `userId`.
|
|
230
|
-
|
|
231
|
-
### Project
|
|
232
|
-
|
|
233
|
-
GPT project with persistent context and memories.
|
|
234
|
-
|
|
235
|
-
| Field | Type | Description |
|
|
236
|
-
|-------|------|-------------|
|
|
237
|
-
| `userId` | ObjectId | Owner |
|
|
238
|
-
| `name` | string | Project name |
|
|
239
|
-
| `systemContext` | string | Prepended to every chat in this project |
|
|
240
|
-
| `memories` | array | `{text, category?, source: "user" \| "auto"}` entries |
|
|
241
|
-
|
|
242
|
-
**Virtual:** `ownerId` aliases `userId`.
|
|
243
|
-
|
|
244
|
-
## Route registrars
|
|
245
|
-
|
|
246
|
-
### addGptRoutes(router, options)
|
|
247
|
-
|
|
248
|
-
| Endpoint | Method | Auth | Description |
|
|
249
|
-
|----------|--------|------|-------------|
|
|
250
|
-
| `/gpt/prompt` | POST | `IsAuthenticated` | SSE streaming chat; body: `prompt`, optional `historyId`, `systemPrompt`, `attachments`, `model`, `projectId` |
|
|
251
|
-
| `/gpt/remix` | POST | `IsAuthenticated` | Non-streaming text remix; body: `{text}` |
|
|
252
|
-
| `/gpt/histories/:id/rating` | PATCH | `IsAuthenticated` | Rate a prompt; body: `{promptIndex, rating: "up" \| "down" \| null}` |
|
|
253
|
-
| `/gpt/tools` | GET | `IsAuthenticated` | List builtin + MCP tools |
|
|
254
|
-
|
|
255
|
-
AI resolution order: `x-ai-api-key` header + `createModelFn` → `createServerModelFn(modelId)` → configured `aiService` → demo SSE response when `demoMode` and none available.
|
|
256
|
-
|
|
257
|
-
### addGptHistoryRoutes(router, options?)
|
|
258
|
-
|
|
259
|
-
CRUD at `/gpt/histories` via `modelRouter`:
|
|
260
|
-
|
|
261
|
-
| Operation | Permission |
|
|
262
|
-
|-----------|------------|
|
|
263
|
-
| Create, List | `IsAuthenticated` |
|
|
264
|
-
| Read, Update, Delete | `IsOwner` |
|
|
265
|
-
|
|
266
|
-
Query filtered by `userId`; sort `-updated`; query fields `userId`, `projectId`.
|
|
267
|
-
|
|
268
|
-
### addProjectRoutes(router, options?)
|
|
269
|
-
|
|
270
|
-
| Endpoint | Method | Auth | Description |
|
|
271
|
-
|----------|--------|------|-------------|
|
|
272
|
-
| `/gpt/projects/:id/memories` | POST | `IsAuthenticated` (owner) | Add memory; body: `{text, category?}` |
|
|
273
|
-
| `/gpt/projects/:id/memories/:memoryId` | DELETE | `IsAuthenticated` (owner) | Remove memory |
|
|
274
|
-
| `/gpt/projects` | CRUD | Create/List: `IsAuthenticated`; Read/Update/Delete: `IsOwner` | Standard modelRouter |
|
|
275
|
-
|
|
276
|
-
### addFileRoutes(router, options)
|
|
277
|
-
|
|
278
|
-
Requires `fileStorageService` and `gcsBucket` (registered by `AiApp` when both are set).
|
|
279
|
-
|
|
280
|
-
| Endpoint | Method | Auth | Description |
|
|
281
|
-
|----------|--------|------|-------------|
|
|
282
|
-
| `/files/upload` | POST | `IsAuthenticated` | Multipart upload (`file` field); allowed MIME: images, PDF, plain text, CSV, JSON |
|
|
283
|
-
| `/files/*gcsKey` | GET | None | Returns signed read URL (1 hour) |
|
|
284
|
-
| `/files/*gcsKey` | DELETE | `IsAuthenticated` (owner) | Soft-delete attachment and remove from GCS |
|
|
285
|
-
|
|
286
|
-
### addMcpRoutes(router, options)
|
|
287
|
-
|
|
288
|
-
Requires `mcpService` (registered by `AiApp` when set).
|
|
289
|
-
|
|
290
|
-
| Endpoint | Method | Auth | Description |
|
|
291
|
-
|----------|--------|------|-------------|
|
|
292
|
-
| `/mcp/servers` | GET | `IsAuthenticated` + admin | Server connection status |
|
|
293
|
-
| `/mcp/tools` | GET | `IsAuthenticated` | Available MCP tools |
|
|
294
|
-
| `/mcp/servers/:name/reconnect` | POST | `IsAuthenticated` + admin | Reconnect one server |
|
|
295
|
-
|
|
296
|
-
### addAiRequestsExplorerRoutes(router, options?)
|
|
297
|
-
|
|
298
|
-
| Endpoint | Method | Auth | Description |
|
|
299
|
-
|----------|--------|------|-------------|
|
|
300
|
-
| `/aiRequestsExplorer` | GET | `IsAuthenticated` + `user.admin` | Paginated AI request log; filters: `requestType`, `model`, `startDate`, `endDate` |
|
|
301
|
-
|
|
302
|
-
## AiApp plugin
|
|
303
|
-
|
|
304
|
-
`AiApp` registers all AI routes in one `TerrenoPlugin`:
|
|
305
|
-
|
|
306
|
-
```typescript
|
|
307
|
-
import {AiApp, AIService, FileStorageService, MCPService} from "@terreno/ai";
|
|
308
|
-
import {google} from "@ai-sdk/google";
|
|
309
|
-
|
|
310
|
-
const aiService = new AIService({model: google("gemini-2.5-flash")});
|
|
311
|
-
|
|
312
|
-
new AiApp({
|
|
313
|
-
aiService,
|
|
314
|
-
fileStorageService: new FileStorageService({bucketName: "my-bucket"}),
|
|
315
|
-
gcsBucket: "my-bucket",
|
|
316
|
-
mcpService: new MCPService([{name: "tools", transport: {type: "sse", url: "..."}}]),
|
|
317
|
-
tools: myToolDefinitions,
|
|
318
|
-
demoMode: false,
|
|
319
|
-
createModelFn: (apiKey, modelId) => google(modelId ?? "gemini-2.5-flash", {apiKey}),
|
|
320
|
-
openApiOptions: options,
|
|
321
|
-
}).register(app);
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
| Option | Description |
|
|
325
|
-
|--------|-------------|
|
|
326
|
-
| `aiService` | Pre-configured server-wide AI service |
|
|
327
|
-
| `createModelFn` | Build model from per-request `x-ai-api-key` |
|
|
328
|
-
| `createServerModelFn` | Server-side model factory (e.g. Vertex ADC) without per-request key |
|
|
329
|
-
| `demoMode` | Return canned responses when no AI service resolves |
|
|
330
|
-
| `fileStorageService` + `gcsBucket` | Enable file upload routes |
|
|
331
|
-
| `mcpService` | Enable MCP routes and tool discovery in chat |
|
|
332
|
-
| `tools` | Static Vercel AI SDK tool definitions for chat |
|
|
333
|
-
| `toolChoice` | `"auto"` \| `"none"` \| `"required"` (default `"auto"` when tools present) |
|
|
334
|
-
| `maxSteps` | Max tool-calling steps (default 5) |
|
|
335
|
-
| `titleModelId` | Cheaper model for conversation title generation |
|
|
336
|
-
| `openApiOptions` | Passed to route OpenAPI builders |
|
|
337
|
-
|
|
338
|
-
## LangfuseApp plugin
|
|
339
|
-
|
|
340
|
-
Optional Langfuse admin UI and tracing:
|
|
341
|
-
|
|
342
|
-
```typescript
|
|
343
|
-
import {LangfuseApp} from "@terreno/ai";
|
|
344
|
-
|
|
345
|
-
new LangfuseApp({
|
|
346
|
-
publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
|
|
347
|
-
secretKey: process.env.LANGFUSE_SECRET_KEY!,
|
|
348
|
-
baseUrl: process.env.LANGFUSE_BASE_URL,
|
|
349
|
-
adminPath: "/admin/langfuse",
|
|
350
|
-
enableTracing: true,
|
|
351
|
-
enableAdminUI: true,
|
|
352
|
-
evaluation: {enabled: true, scoringFunctions: [...]},
|
|
353
|
-
}).register(app);
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
| Option | Default | Description |
|
|
357
|
-
|--------|---------|-------------|
|
|
358
|
-
| `publicKey`, `secretKey` | — | Langfuse API keys (required) |
|
|
359
|
-
| `baseUrl` | — | Langfuse host |
|
|
360
|
-
| `adminPath` | `"/admin/langfuse"` | Admin route prefix |
|
|
361
|
-
| `organization` | maintainer default | Langfuse organization slug — set your own |
|
|
362
|
-
| `project` | `"terreno"` | Langfuse project slug — set your own |
|
|
363
|
-
| `enableTracing` | `true` | OpenTelemetry via `@langfuse/otel` |
|
|
364
|
-
| `enableAdminUI` | `true` | Prompt, trace, playground, evaluation routes |
|
|
365
|
-
| `evaluation.enabled` | — | Register evaluation scoring routes |
|
|
366
|
-
| `cache` | — | Prompt/trace TTL overrides |
|
|
367
|
-
|
|
368
|
-
Calls `shutdownLangfuseClient()` and `shutdownTracing()` on `SIGTERM`.
|
|
369
|
-
|
|
370
|
-
## Langfuse integration
|
|
371
|
-
|
|
372
|
-
Low-level exports (also used by `addGptRoutes` when `langfuseSystemPromptName` is set):
|
|
373
|
-
|
|
374
|
-
- **Client:** `initLangfuseClient`, `getLangfuseClient`, `isLangfuseInitialized`, `shutdownLangfuseClient`
|
|
375
|
-
- **Prompts:** `getPrompt`, `createPrompt`, `compilePrompt`, `invalidatePromptCache`, `preparePromptForAI`
|
|
376
|
-
- **Tracing:** `initTracing`, `shutdownTracing`, `createTelemetryConfig`
|
|
377
|
-
- **Cache:** `LangfuseCache`, `getCached`, `setCached`, `invalidateCache`
|
|
378
|
-
|
|
379
|
-
Subpath imports for tree-shaking: `@terreno/ai/langfuseClient`, `@terreno/ai/langfuseApp`.
|
|
380
|
-
|
|
381
|
-
## FileStorageService
|
|
382
|
-
|
|
383
|
-
Google Cloud Storage helper for uploads referenced by `addFileRoutes`.
|
|
384
|
-
|
|
385
|
-
```typescript
|
|
386
|
-
const storage = new FileStorageService({
|
|
387
|
-
bucketName: "my-bucket",
|
|
388
|
-
storageOptions: {}, // optional @google-cloud/storage options
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
await storage.upload({buffer, filename, mimeType, userId});
|
|
392
|
-
await storage.getSignedUrl(gcsKey); // 1-hour v4 signed URL
|
|
393
|
-
await storage.delete(gcsKey); // GCS delete + soft-delete FileAttachment
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
## MCPService
|
|
397
|
-
|
|
398
|
-
Manages SSE MCP client connections for tool calling.
|
|
399
|
-
|
|
400
|
-
```typescript
|
|
401
|
-
const mcp = new MCPService([
|
|
402
|
-
{name: "my-server", transport: {type: "sse", url: "https://...", headers: {...}}},
|
|
403
|
-
]);
|
|
404
|
-
await mcp.connect();
|
|
405
|
-
const tools = await mcp.getTools();
|
|
406
|
-
const status = mcp.getServerStatus();
|
|
407
|
-
await mcp.reconnectServer("my-server");
|
|
408
|
-
await mcp.disconnect();
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
## Gemini and Vertex helpers
|
|
412
|
-
|
|
413
|
-
**Gemini Developer API** (API-key based):
|
|
414
|
-
|
|
415
|
-
```typescript
|
|
416
|
-
import {listGeminiApiModels, normalizeGeminiModelId, GEMINI_API_BASE_URL} from "@terreno/ai";
|
|
417
|
-
|
|
418
|
-
const models = await listGeminiApiModels({apiKey: "..."});
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
**Vertex AI / Gemini Enterprise:**
|
|
422
|
-
|
|
423
|
-
```typescript
|
|
424
|
-
import {
|
|
425
|
-
createVertexProvider,
|
|
426
|
-
listEnabledVertexModels,
|
|
427
|
-
assertVertexModelsEnabled,
|
|
428
|
-
DEFAULT_VERTEX_LOCATION,
|
|
429
|
-
} from "@terreno/ai";
|
|
430
|
-
|
|
431
|
-
const vertex = await createVertexProvider({project: "my-gcp-project"});
|
|
432
|
-
const model = vertex.languageModel("gemini-2.5-flash");
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
Env fallbacks: `GOOGLE_VERTEX_PROJECT`, `GOOGLE_VERTEX_LOCATION` (default `us-central1`).
|
|
436
|
-
|
|
437
|
-
## Web search types
|
|
438
|
-
|
|
439
|
-
`WebSearchProvider` and `WebSearchResult` define a pluggable search interface for custom Vercel AI SDK tools. The package does not ship a default provider — implement `search(query)` and wire it into a `tool()` passed to `AiApp` `tools`.
|
|
440
|
-
|
|
441
|
-
## Integration example
|
|
442
|
-
|
|
443
|
-
```typescript
|
|
444
|
-
import {TerrenoApp} from "@terreno/api";
|
|
445
|
-
import {AiApp, AIService, LangfuseApp} from "@terreno/ai";
|
|
446
|
-
import {google} from "@ai-sdk/google";
|
|
447
|
-
|
|
448
|
-
const aiService = new AIService({model: google("gemini-2.5-flash")});
|
|
449
|
-
|
|
450
|
-
new TerrenoApp({userModel: User})
|
|
451
|
-
.register(new AiApp({aiService, openApiOptions: {}}))
|
|
452
|
-
.register(
|
|
453
|
-
new LangfuseApp({
|
|
454
|
-
publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
|
|
455
|
-
secretKey: process.env.LANGFUSE_SECRET_KEY!,
|
|
456
|
-
})
|
|
457
|
-
)
|
|
458
|
-
.start();
|
|
459
|
-
```
|
|
460
|
-
|
|
461
|
-
Legacy `setupServer` pattern: call `addGptHistoryRoutes`, `addGptRoutes`, etc. inside `addRoutes`.
|
|
462
|
-
|
|
463
|
-
## Environment variables
|
|
464
|
-
|
|
465
|
-
| Variable | Used by | Description |
|
|
466
|
-
|----------|---------|-------------|
|
|
467
|
-
| `GOOGLE_VERTEX_PROJECT` | `createVertexProvider` | GCP project for Vertex models |
|
|
468
|
-
| `GOOGLE_VERTEX_LOCATION` | `createVertexProvider` | Vertex region (default `us-central1`) |
|
|
469
|
-
| `LANGFUSE_PUBLIC_KEY` | `LangfuseApp` | Langfuse public key |
|
|
470
|
-
| `LANGFUSE_SECRET_KEY` | `LangfuseApp` | Langfuse secret key |
|
|
471
|
-
| `LANGFUSE_BASE_URL` | Langfuse client | Langfuse host URL |
|
|
472
|
-
|
|
473
|
-
GCS credentials use standard Google Cloud Application Default Credentials for `FileStorageService`.
|
|
474
|
-
|
|
475
|
-
## Conventions
|
|
476
|
-
|
|
477
|
-
- Use `aiModel` on `AIRequest`, not `model` (Mongoose reserved name).
|
|
478
|
-
- `GptHistory`, `FileAttachment`, and `Project` use `userId` with `ownerId` virtual for `Permissions.IsOwner`.
|
|
479
|
-
- Gpt history list uses `queryFilter: (user) => ({userId: user?.id})`, not `OwnerQueryFilter`.
|
|
480
|
-
- Express user in routes: `(req.user as {_id?: ObjectId})` casting pattern.
|
|
481
|
-
- Throw `APIError` with appropriate status; check conditions early.
|
|
482
|
-
- Uses `Model.findOneOrNone` / `findExactlyOne` — never raw `findOne`.
|
|
483
|
-
|
|
484
|
-
## Testing
|
|
485
|
-
|
|
486
|
-
- Framework: `bun test` with preload `./src/tests/bunSetup.ts`
|
|
487
|
-
- HTTP: supertest against real routes
|
|
488
|
-
- DB: memory Mongo via `@terreno/test` (`TERRENO_TEST_USE_MEMORY_MONGO` or `TERRENO_TEST_MONGODB_URI`)
|
|
489
|
-
- Mock AI model: implement `doGenerate` and `doStream` on a fake `LanguageModel`
|
|
490
|
-
|
|
491
|
-
```typescript
|
|
492
|
-
const createMockModel = () => ({
|
|
493
|
-
doGenerate: mock(async () => ({
|
|
494
|
-
finishReason: "stop" as const,
|
|
495
|
-
rawCall: {rawPrompt: "", rawSettings: {}},
|
|
496
|
-
text: "response text",
|
|
497
|
-
usage: {completionTokens: 10, promptTokens: 5},
|
|
498
|
-
})),
|
|
499
|
-
doStream: mock(async () => ({
|
|
500
|
-
rawCall: {rawPrompt: "", rawSettings: {}},
|
|
501
|
-
stream: new ReadableStream({
|
|
502
|
-
start(controller) {
|
|
503
|
-
controller.enqueue({type: "text-delta" as const, textDelta: "chunk "});
|
|
504
|
-
controller.enqueue({
|
|
505
|
-
type: "finish" as const,
|
|
506
|
-
finishReason: "stop" as const,
|
|
507
|
-
usage: {completionTokens: 10, promptTokens: 5},
|
|
508
|
-
});
|
|
509
|
-
controller.close();
|
|
510
|
-
},
|
|
511
|
-
}),
|
|
512
|
-
})),
|
|
513
|
-
modelId: "mock-model",
|
|
514
|
-
provider: "mock-provider",
|
|
515
|
-
specificationVersion: "v1" as const,
|
|
516
|
-
});
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
Never mock `@terreno/api` or Mongoose models — test against real functionality.
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
# @terreno/test
|
|
2
|
-
|
|
3
|
-
Shared Bun test helpers for Terreno backend packages: in-memory MongoDB lifecycle, auth env defaults, HTTP fixtures, and log silencing.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
bun add -d @terreno/test mongoose
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
`mongoose` is a peer dependency (>= 8.0.0).
|
|
12
|
-
|
|
13
|
-
## Commands
|
|
14
|
-
|
|
15
|
-
From the `@terreno/test` package directory:
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
bun run compile # Compile TypeScript
|
|
19
|
-
bun run test # Run package tests
|
|
20
|
-
bun run lint # Lint code
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
Consumers typically run `bun test` in their own package with a `bunfig.toml` preload (see below).
|
|
24
|
-
|
|
25
|
-
## Preload pattern
|
|
26
|
-
|
|
27
|
-
Add a `bunfig.toml` preload that wires MongoDB and test env before any test file runs. Example from `admin-backend/bunfig.toml`:
|
|
28
|
-
|
|
29
|
-
```toml
|
|
30
|
-
[test]
|
|
31
|
-
preload = ["./src/tests/bunSetup.ts"]
|
|
32
|
-
root = "./src"
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Example preload (`admin-backend/src/tests/bunSetup.ts`):
|
|
36
|
-
|
|
37
|
-
```typescript
|
|
38
|
-
import {registerSimpleMongoPreload} from "@terreno/test";
|
|
39
|
-
|
|
40
|
-
process.env.TERRENO_TEST_USE_MEMORY_MONGO = "true";
|
|
41
|
-
|
|
42
|
-
registerSimpleMongoPreload({
|
|
43
|
-
testEnv: {
|
|
44
|
-
tokenIssuer: "terreno-admin-backend.test",
|
|
45
|
-
},
|
|
46
|
-
});
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
The `@terreno/api` package uses a two-file preload (`api/bunfig.toml`): `./src/tests/testEnv.ts` then `./src/tests/bunSetup.ts`, which calls `registerBackendPreload` or `registerSimpleMongoPreload` depending on fixture-cache settings.
|
|
50
|
-
|
|
51
|
-
Import the memory-Mongo flag alone when you only need the env var:
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
import "@terreno/test/preload/memoryMongo";
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
That sets `TERRENO_TEST_USE_MEMORY_MONGO=true` before other preload logic runs.
|
|
58
|
-
|
|
59
|
-
## Test environment
|
|
60
|
-
|
|
61
|
-
Call `setTerrenoTestEnv()` from a preload or `beforeEach` to apply canonical auth secrets and validate required vars (via internal `setupTestEnvironment()`):
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
import {setTerrenoTestEnv} from "@terreno/test";
|
|
65
|
-
|
|
66
|
-
setTerrenoTestEnv({
|
|
67
|
-
tokenIssuer: "my-package.test",
|
|
68
|
-
tokenSecret: "secret",
|
|
69
|
-
refreshTokenSecret: "refresh",
|
|
70
|
-
sessionSecret: "session",
|
|
71
|
-
});
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Defaults: `TOKEN_SECRET`, `TOKEN_ISSUER`, `REFRESH_TOKEN_SECRET`, `SESSION_SECRET`, `NODE_ENV=test`, `TZ=UTC`.
|
|
75
|
-
|
|
76
|
-
## Environment variables
|
|
77
|
-
|
|
78
|
-
| Variable | Effect |
|
|
79
|
-
|----------|--------|
|
|
80
|
-
| `TERRENO_TEST_USE_MEMORY_MONGO` | When `"true"`, `registerSimpleMongoPreload` starts `mongodb-memory-server` if `TERRENO_TEST_MONGODB_URI` is unset. |
|
|
81
|
-
| `TERRENO_TEST_MONGODB_URI` | External MongoDB URI. Takes priority over in-memory server in `startMongoServer` and `registerSimpleMongoPreload`. |
|
|
82
|
-
| `BUN_TEST_DISABLE_DB` | When `"true"`, `registerBackendPreload` skips all Mongo `beforeAll`/`afterAll` hooks (no DB startup). |
|
|
83
|
-
|
|
84
|
-
`startMongoServer` also publishes the resolved URI to `TERRENO_TEST_MONGO_URI` and honors `TERRENO_TEST_USE_REPLSET=true` for replica-set memory servers.
|
|
85
|
-
|
|
86
|
-
## Exported helpers
|
|
87
|
-
|
|
88
|
-
| Export | Description |
|
|
89
|
-
|--------|-------------|
|
|
90
|
-
| `registerBackendPreload` | Full lifecycle: memory/external Mongo, optional transactions, Sentry mock, log silencing. |
|
|
91
|
-
| `registerSimpleMongoPreload` | Lightweight connect-once pattern (used by most packages). |
|
|
92
|
-
| `setTerrenoTestEnv` | Apply and validate auth test env vars. |
|
|
93
|
-
| `startMongoServer` / `stopMongoServer` | Start or stop shared in-memory Mongo and connect mongoose. |
|
|
94
|
-
| `getMongoServerUri` | Resolved URI after `startMongoServer`. |
|
|
95
|
-
| `getBaseServer` | Build an Express app for supertest from route registrars. |
|
|
96
|
-
| `authAsUser` | Login helper returning auth headers for supertest. |
|
|
97
|
-
| `createMongoTestCache` | Fixture-cache controller for fast `@terreno/api` tests. |
|
|
98
|
-
| `registerLogSilencing` / `createLogSilencer` | Suppress Winston noise in tests. |
|
|
99
|
-
| `registerSentryBunMock` | Mock `@sentry/bun` in preload. |
|
|
100
|
-
| `ensureTestMongooseConnected` | Connect mongoose to test URI with retries. |
|
|
101
|
-
| `waitForDocument` / `waitForDocuments` | Poll until documents match a query. |
|
|
102
|
-
| `startTestTransaction` / `abortTestTransaction` | Per-test mongoose transactions when enabled. |
|
|
103
|
-
|
|
104
|
-
## Conventions
|
|
105
|
-
|
|
106
|
-
- Preload once per package via `bunfig.toml`; do not start Mongo in individual test files.
|
|
107
|
-
- Prefer `registerSimpleMongoPreload` unless you need transactions or fixture caching (`registerBackendPreload`).
|
|
108
|
-
- Never mock `@terreno/api` or Mongoose models in package tests — use the real stack against memory Mongo.
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# Roadmap
|
|
2
|
-
|
|
3
|
-
Terreno's public roadmap lives on GitHub:
|
|
4
|
-
|
|
5
|
-
- **[ROADMAP.md](https://github.com/FlourishHealth/terreno/blob/master/ROADMAP.md)** — generated from the Terreno Roadmap project board (also in the repo root)
|
|
6
|
-
- **[Roadmap process](explanation/roadmap-process.md)** — Discussions, triage, Linear bridge, maintainer setup
|
|
7
|
-
- **[GitHub Discussions](https://github.com/FlourishHealth/terreno/discussions)** — Ideas, Q&A, RFCs
|
|
8
|
-
|
|
9
|
-
To propose work, start an [Ideas discussion](https://github.com/FlourishHealth/terreno/discussions/new?category=ideas) rather than opening a tracking issue directly.
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# Task lists
|
|
2
|
-
|
|
3
|
-
Bot-consumable execution checklists, one per implementation plan (IP). A task file is
|
|
4
|
-
the second half of the pair described in
|
|
5
|
-
[`docs/implementationPlans/README.md`](../implementationPlans/README.md):
|
|
6
|
-
|
|
7
|
-
- **IP** (`docs/implementationPlans/<slug>.md`) — the design: what and why.
|
|
8
|
-
- **Task list** (`docs/tasks/<slug>.md`) — the steps: the concrete, ordered work.
|
|
9
|
-
|
|
10
|
-
The filename slug matches the IP it belongs to.
|
|
11
|
-
|
|
12
|
-
## Task shape
|
|
13
|
-
|
|
14
|
-
Each task is a checkbox with four fields so it can be picked up and verified independently:
|
|
15
|
-
|
|
16
|
-
```markdown
|
|
17
|
-
- [ ] **Task 1.1**: Short title
|
|
18
|
-
- Description: what to implement
|
|
19
|
-
- Files: expected files to create or modify
|
|
20
|
-
- Depends on: none | other task IDs
|
|
21
|
-
- Acceptance: how to verify it is done
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
Group tasks by phase (`### Phase 1: …`). Order them by dependency — models first, then
|
|
25
|
-
APIs, then UI. Blend-style runs may append a **Plan vs Actual** log to the same file after
|
|
26
|
-
each task.
|
|
27
|
-
|
|
28
|
-
## What lives here vs elsewhere
|
|
29
|
-
|
|
30
|
-
| Concern | Home |
|
|
31
|
-
| ------- | ---- |
|
|
32
|
-
| Design, scope, acceptance criteria | the IP (`docs/implementationPlans/`) |
|
|
33
|
-
| Concrete task steps and their status | this directory |
|
|
34
|
-
| Public status and target | GitHub roadmap issue / Project (roadmap-enabled repos) |
|
|
35
|
-
| Sprint estimates and assignees | Linear |
|
|
36
|
-
|
|
37
|
-
Do not copy the full checklist into a GitHub issue or Linear. Create linked GitHub child
|
|
38
|
-
issues only for tasks that outside contributors should be able to claim independently; the
|
|
39
|
-
task file stays the source of truth for scope and acceptance.
|
|
40
|
-
|
|
41
|
-
The docs site excludes this directory, so link to task files with full GitHub URLs from
|
|
42
|
-
pages that render on the site.
|