Skip to content

Commit 23e11e8

Browse files
committed
check in current worktree snapshot
1 parent 22536ed commit 23e11e8

212 files changed

Lines changed: 31552 additions & 2008 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,64 @@
1-
# Rule: AI Provider Standards (Antigravity)
2-
3-
## 1. Zod Supremacy
4-
- Every structured AI call (`generateStructuredResponse`, `generateStructuredWithTools`) MUST accept a `z.ZodType<T>` payload.
5-
- Weak interfaces (`any` or `Record<string, unknown>`) are forbidden for output generation.
6-
- Use `zod-to-json-schema` to natively pipe the schema into the payload's `response_format` for supported compat endpoints.
7-
- Always call `schema.parse(rawParsed)` on the final JSON result to guarantee structural integrity.
8-
9-
## 2. Universal File Context
10-
- Any method ending in `*FromFiles` must handle payloads consisting of `FileInput` objects (`{ name, type, data, isBase64 }`).
11-
- Providers with native file processing (e.g., Gemini's `inlineData`) should construct standard multi-part arrays.
12-
- Providers without native large-file limits (e.g., Worker AI) MUST use the transparent Vectorize RAG chunking algorithm if the total string length exceeds 6,000 characters to prevent hitting input limits.
13-
14-
## 3. Jules SDK Integration
15-
- Since Jules operates via long-running chat streams, large structured responses should be handled by getting broad context from Jules, and piping its output into `worker-ai` `generateStructuredResponse` to enforce strict formatting.
16-
- Explicit reasoning and agent orchestration features (`analyzeRepo`, `completeTask`, `createPlan`) should exclusively utilize Jules.
17-
18-
## 4. No Vercel AI SDK
19-
- Under no circumstances will you import `ai` or `@ai-sdk/`. It has been banned due to edge runtime parsing inconsistencies on Workers.
20-
- Use the native `fetch` API against the Cloudflare AI Gateway instead.
1+
# AI Provider Standards
2+
3+
## URL Construction (CRITICAL)
4+
5+
**NEVER** manually construct AI Gateway URLs or append endpoint paths. Use `AIGateway.getBaseUrl()` with the `endpoint` option — it returns the **full URL** ready for `fetch()`.
6+
7+
```typescript
8+
// ✅ CORRECT — endpoint specified, baseUrl is the complete URL
9+
const { baseUrl } = await AIGateway.getBaseUrl(env, { provider: 'openai', endpoint: 'chat' });
10+
const res = await fetch(baseUrl, { ... });
11+
12+
// ✅ CORRECT — raw base for Gemini's custom native path
13+
const { baseUrl } = await AIGateway.getBaseUrl(env, { provider: 'gemini' });
14+
const res = await fetch(`${baseUrl}/v1beta/models/${model}:generateContent`, { ... });
15+
16+
// ❌ FORBIDDEN — manual path appending defeats centralization
17+
const { baseUrl } = await AIGateway.getBaseUrl(env, { provider: 'openai' });
18+
const res = await fetch(`${baseUrl}/v1/chat/completions`, { ... });
19+
```
20+
21+
### Endpoint Options
22+
- `endpoint: 'chat'` → appends `/v1/chat/completions`
23+
- `endpoint: 'models'` → appends `/v1/models`
24+
- No endpoint → raw gateway URL (for Gemini native path only)
25+
26+
## Authentication
27+
28+
- **BYOK Mode** (`AI_GATEWAY_TOKEN` set): Only send `cf-aig-authorization: Bearer {token}`. Do NOT send `Authorization` header — the gateway injects stored provider keys.
29+
- **Direct Mode** (`AI_GATEWAY_TOKEN` absent): Send `Authorization: Bearer {apiKey}` as usual.
30+
31+
## Imports
32+
33+
- **Canonical**: `import { AIGateway } from '@/ai/providers/ai-gateway'`
34+
- **Legacy re-export**: `@/ai/utils/ai-gateway` still works but is deprecated
35+
36+
## Logging
37+
38+
All AI providers MUST use the `Logger` class from `src/lib/logger.ts` (NOT raw `console.log`/`console.error`).
39+
40+
> See `.agent/rules/traceability-logging.md` for full enforcement rules.
41+
42+
Standard source overrides:
43+
44+
| Provider | Source Override |
45+
|----------|----------------|
46+
| AI Gateway | `'AIGateway'` |
47+
| Workers AI | `'WorkerAI'` |
48+
| OpenAI | `'OpenAI'` |
49+
| Anthropic | `'Anthropic'` |
50+
| Gemini | `'Gemini'` |
51+
| Router | `'AIRouter'` |
52+
| Health | `'GatewayHealth'` |
53+
| Diagnostician | `'Diagnostician'` |
54+
55+
## Provider Files
56+
57+
| Provider | File | Status |
58+
|----------|------|--------|
59+
| Gateway | `src/ai/providers/ai-gateway.ts` | Source of truth |
60+
| Config | `src/ai/providers/config.ts` | Model resolution only — NO gateway URLs |
61+
| Workers AI | `src/ai/providers/worker-ai.ts` | Uses gateway client |
62+
| OpenAI | `src/ai/providers/openai.ts` | Uses gateway client |
63+
| Anthropic | `src/ai/providers/anthropic.ts` | Uses gateway client |
64+
| Gemini | `src/ai/providers/gemini.ts` | Uses native client via `getBaseUrl()` |

.agent/rules/ai-providers.md

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,49 @@
11
# Protocol: AI Provider Routing & Resolution
22

3-
**MANDATORY IMPORT PATH**: Agents must _always and exclusively_ import AI functions from `@/ai/providers`.
4-
**FORBIDDEN IMPORTS**: It is _never_ acceptable to import directly from specific provider files (e.g., `ai/providers/openai`, `ai/providers/gemini`) or the index file explicitly (e.g., `ai/providers/index`).
3+
**`@/ai/providers/index.ts`** is the **single public API** for all AI generation.
54

6-
**FUNCTION USAGE**: When using functions like `generateText`, `generateStructuredResponse`, etc., the agent should specify the `provider` and `model` arguments when known.
5+
## Mandatory Import Path
76

8-
**FALLBACK BEHAVIOR**:
7+
Callers must _always and exclusively_ import AI functions from `@/ai/providers`:
98

10-
- If no provider or model is provided by the caller, the system relies on the `index.ts` routing to default to `worker-ai`, which then utilizes its internal business logic to select the correct fallback model.
11-
- Similarly, if a provider is specified but no model is provided, the specific provider module's logic determines the default model.
12-
- Agents should not hardcode default models unless explicitly required by the business logic.
9+
```typescript
10+
// ✅ CORRECT
11+
import { generateText, generateStructuredResponse } from "@/ai/providers";
12+
const result = await generateText(env, prompt, system);
13+
14+
// ❌ FORBIDDEN — pre-resolving provider/model
15+
import { resolveDefaultAiProvider, resolveDefaultAiModel } from "@/ai/agents/support/agent-ai";
16+
const provider = resolveDefaultAiProvider(env);
17+
const model = resolveDefaultAiModel(env, provider);
18+
const result = await AIGateway.runTextWithFallback(env, provider, model, system, prompt);
19+
20+
// ❌ FORBIDDEN — direct provider imports
21+
import { generateText } from "@/ai/providers/openai";
22+
23+
// ❌ FORBIDDEN — config imports in external code
24+
import { resolveDefaultAiModel } from "@/ai/providers/ai-gateway/config";
25+
```
26+
27+
## Resolution Behavior
28+
29+
- If **no provider or model** is passed, the system defaults to `worker-ai` via `resolveInvocation()`.
30+
- If a **provider** is specified but no model, the default model for that provider is resolved internally.
31+
- If a **model** is specified via `AIOptions.model`, it is passed through; provider defaults to `worker-ai`.
32+
33+
## Forbidden Imports (External Code)
34+
35+
External code (routes, services, automations, workflows) must **NEVER** import:
36+
37+
1. `resolveDefaultAiProvider` or `resolveDefaultAiModel` from anywhere
38+
2. `AIGateway` class directly
39+
3. Individual provider modules (`@/ai/providers/openai`, `@/ai/providers/gemini`, etc.)
40+
4. `@/ai/providers/ai-gateway/config`
41+
42+
## Allowed Exceptions
43+
44+
These files are **internal** to the AI subsystem and may import resolvers:
45+
46+
- `ai/agents/support/inference.ts` — internal agent helpers
47+
- `ai/agents/support/agent-ai.ts` — legacy compat layer
48+
- `ai/agents/runtime/openai.ts` — Agent SDK compat shim
49+
- `routes/api/agents/models.ts` — model listing endpoint (needs `resolveDefaultAiModel` for defaults display)

.agent/rules/error-handling.md

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,25 @@ When an error occurs anywhere in the stack, we must ensure it is persistently lo
77
Whenever a backend tool, AI agent, or API action fails, you **MUST** record the failure into the D1 `system_logs` table.
88

99
- **Import the Logger**: `import { Logger } from '@/lib/logger'`
10-
- **Initialize**: `const logger = new Logger(env, 'ContextName');`
11-
- **Record**: `logger.error("Description", { details: error.message, ...context })`
12-
- **Mandatory Flush**: Call `await logger.flush()` before the request terminates to commit the array of logs to the database.
10+
- **Initialize**:
11+
```typescript
12+
import { Logger } from '@/lib/logger';
13+
// Example inside a class
14+
constructor(protected readonly env: Env, loggerNamespace = 'orchestration/base') {
15+
this.logger = new Logger(env, loggerNamespace);
16+
}
17+
```
18+
- **Record**: `this.logger.error("Description", { details: error.message, ...context })`
19+
- **Mandatory Flush**: Call `await this.logger.flush()` before the request terminates to commit the array of logs to the database.
20+
21+
### No Error Truncation (Strictly Enforced)
22+
We never want to truncate error messages or inputs. Truncated data hides root causes and is useless for debugging.
23+
24+
```typescript
25+
this.logger.debug(`Running orchestration for: ${input.slice(0, 100)}...`); // we never want to truncate the error message, why would that be helpful when debugging? it wouldnt.
26+
27+
this.logger.debug(`Running orchestration for: ${input}`);
28+
```
1329

1430
## 2. Frontend Error UI (Shadcn + Copy)
1531
When a frontend component catches an error, you **MUST** pass the literal error string to the centralized error service. This service invokes a Shadcn Sonner toast that includes the raw error stack and a "Copy to Clipboard" button.
@@ -28,7 +44,12 @@ When a frontend component catches an error, you **MUST** pass the literal error
2844
handleGlobalError(err);
2945
}
3046
```
31-
- **Forbidden**: Do not use `console.error(err)` or raw `toast.error()` directly for system or API errors. Do not write local `<Alert variant="destructive">` blocks for API failures unless it's a localized form validation constraint. Use `handleGlobalError()` exclusively, which handles deduplication and backend metric dispatching automatically.
47+
- **Forbidden**: Do not use `console.error(err)` or raw `toast.error()` directly for system or API errors. Do not write local `<Alert variant="destructive">` blocks for API failures unless it's a localized form validation constraint. Use `handleGlobalError()` exclusively, which handles deduplication and backend metric dispatching automatically. This is strictly enforced and mandatory.
48+
49+
```tsx
50+
import { handleGlobalError } from "@/lib/error-handler";
51+
handleGlobalError(`Failed to apply decision. ${res}`);
52+
```
3253

3354
## 3. Strict Passthrough
3455
Agents must ensure that backend routes return the actual error string generated by the failed service (e.g. GitHub API 404s, Stripe 402s).

.agent/rules/globals.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
1-
# Rule: Global Env Type Enforcement
1+
---
2+
trigger: always_on
3+
---
4+
5+
# Rule: Global Env Type and Hono Bindings Enforcement
6+
7+
8+
- **Strict Prohibition**: You are forbidden from using `import { Bindings } from '@utils/hono';`.
9+
- **Global Context**: The `Env` type is generated by `wrangler types` and made global via `tsconfig.json`.
10+
- **Usage Pattern**:
11+
-`const app = new Hono<{ Bindings: Env }>();`
12+
-`import { Bindings } ... const app = new Hono<{ Bindings: Bindings }>();`
213

314
## 1. Global Definition
415

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Infrastructure & Package Management Standards
2+
3+
- **Package Manager**: `pnpm` is the mandatory package manager for this project.
4+
- **CLI Execution**:
5+
- Never use `npx`.
6+
- Always use `pnpm dlx wrangler@latest` for Cloudflare Workers/Pages interactions to prevent version mismatch.
7+
- Use `pnpm exec` for locally installed binary execution that does not require the `@latest` check.
8+
- **Configuration**: The `.npmrc` file must remain clean of keys that cause warnings in standard Node.js environments.
9+
- **Agent Awareness**: All implementation plans generated by the agent must default to `pnpm` commands.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
trigger: always_on
3+
---
4+
5+
{
6+
"$schema": "https://json-schema.org/draft/2020-12/schema",
7+
"title": "Stitch Baton Prompt Schema",
8+
"description": "Schema for the .stitch/next-prompt.md file to ensure agent compliance with the Monolith Design System.",
9+
"type": "object",
10+
"required": ["page", "status", "prompt_content"],
11+
"properties": {
12+
"page": {
13+
"type": "string",
14+
"description": "The target filename without extension (e.g., 'dashboard'). Must exist in SITE.md."
15+
},
16+
"status": {
17+
"type": "string",
18+
"enum": ["todo", "in-progress", "review", "done"],
19+
"default": "todo"
20+
},
21+
"prompt_content": {
22+
"type": "object",
23+
"required": ["description", "design_system", "page_structure", "technical_requirements"],
24+
"properties": {
25+
"description": {
26+
"type": "string",
27+
"description": "One-line purpose with vibe keywords (Brutalist, Obsidian, Tonal, Asymmetric)."
28+
},
29+
"design_system": {
30+
"type": "object",
31+
"description": "Strict adherence to DESIGN.md Section 6.",
32+
"required": ["constraints", "palette"],
33+
"properties": {
34+
"constraints": {
35+
"type": "array",
36+
"items": { "type": "string" },
37+
"default": [
38+
"Strict No-Line Rule: Forbidden to use 1px solid borders for containment.",
39+
"System-First Interface: NO user icons or profiles anywhere.",
40+
"No Search: Layout must be intuitive enough that search inputs are unnecessary.",
41+
"Collapsible Sidebar: The shadcn/ui sidebar must be available and collapsible on every page."
42+
]
43+
},
44+
"palette": {
45+
"type": "string",
46+
"default": "Zinc Dark / Obsidian scale using OKLCH(0.145 0 0) background."
47+
}
48+
}
49+
},
50+
"page_structure": {
51+
"type": "array",
52+
"description": "Numbered sections to build.",
53+
"items": { "type": "string" },
54+
"minItems": 3
55+
},
56+
"technical_requirements": {
57+
"type": "array",
58+
"description": "Specific Shadcn components or Cloudflare bindings.",
59+
"items": { "type": "string" },
60+
"default": ["shadcn/ui Sidebar (Collapsible)", "assistant-ui Thread (if applicable)"]
61+
}
62+
}
63+
}
64+
}
65+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Rule: Mandatory Traceability & Structured Logging
2+
3+
## Core Mandate (Non-Negotiable)
4+
5+
**ALL backend code MUST use the `Logger` class from `src/lib/logger.ts` for logging.** This class outputs structured JSON to console AND mirrors every log entry to D1 (`system_logs` table) for persistence and auditability.
6+
7+
### Forbidden Patterns
8+
9+
```typescript
10+
// ❌ FORBIDDEN — raw console calls bypass D1 mirroring
11+
console.log("something happened");
12+
console.error("something failed:", error);
13+
console.warn("warning");
14+
15+
// ❌ FORBIDDEN — truncating error messages or inputs hides root cause
16+
this.logger.debug(`Running orchestration for: ${input.slice(0, 100)}...`);
17+
logger.error(`failed`, { body: errBody.substring(0, 200) });
18+
```
19+
20+
### Required Pattern
21+
22+
```typescript
23+
import { Logger } from '@/lib/logger';
24+
25+
// ✅ CORRECT — Logger instance per class, with source override
26+
constructor(protected readonly env: Env, loggerNamespace = 'orchestration/base') {
27+
this.logger = new Logger(env, loggerNamespace);
28+
}
29+
this.logger.debug(`Running orchestration for: ${input}`);
30+
this.logger.error('Operation failed', { error: error.message, stack: error.stack, responseBody: fullBody });
31+
await this.logger.flush(); // MUST flush before returning or throwing
32+
```
33+
34+
### Full Error Bodies (MANDATORY)
35+
36+
When logging error responses or inputs, you MUST log the **complete** string or error body. Truncating with `.slice()`, `.substring()`, or any other method is **strictly forbidden**. Truncated strings are useless for debugging and hide root causes.
37+
38+
```typescript
39+
// ❌ WRONG
40+
this.logger.debug(`Running orchestration for: ${input.slice(0, 100)}...`);
41+
const body = await res.text();
42+
logger.error('API failed', { body: body.slice(0, 200) });
43+
44+
// ✅ CORRECT
45+
this.logger.debug(`Running orchestration for: ${input}`);
46+
const body = await res.text();
47+
logger.error('API failed', { status: res.status, body });
48+
```
49+
50+
## Agent Evaluation Duty (MANDATORY)
51+
52+
Every time an agent evaluates, reviews, modifies, or creates code, it MUST also evaluate:
53+
54+
1. **Traceability Coverage**: Does every significant code path (entry points, error handlers, external API calls, state transitions) have adequate logging?
55+
2. **Logger Usage**: Is the code using `Logger` from `src/lib/logger.ts`? If it uses raw `console.log`/`console.error`/`console.warn`, the agent MUST migrate it.
56+
3. **Error Completeness**: Are error messages logged in full, without `.slice()`, `.substring()`, or truncation?
57+
4. **Flush Discipline**: Is `await logger.flush()` called before every early return, throw, or function exit in error paths?
58+
59+
### When to Add Logging
60+
61+
- **New features**: Every public function must log entry with key parameters
62+
- **Error handlers**: Every `catch` block must log the full error with stack trace
63+
- **External calls**: Every `fetch()` to an external API must log the request (URL, method) and response (status, body on failure)
64+
- **State transitions**: Workflow steps, agent state changes, and provider switches must be logged
65+
66+
### Standard Source Overrides
67+
68+
| Component | Source Override |
69+
|-----------|----------------|
70+
| AI Gateway | `'AIGateway'` |
71+
| Workers AI | `'WorkerAI'` |
72+
| OpenAI | `'OpenAI'` |
73+
| Anthropic | `'Anthropic'` |
74+
| Gemini | `'Gemini'` |
75+
| AI Router | `'AIRouter'` |
76+
| Gateway Health | `'GatewayHealth'` |
77+
| Diagnostician | `'Diagnostician'` |
78+
| Webhook handler | `'Webhooks'` |
79+
| Health checks | `'HealthCheck'` |
80+
| MCP tools | `'MCP:<ToolName>'` |
81+
| Workflows | `'Workflow:<Name>'` |

0 commit comments

Comments
 (0)