Skip to content

Chapter 2 · Project Setup and Development Workflow ​

Chapter goals: Initialize a Flue project from scratch, understand directory conventions, and run both "local CLI" and "dev server" paths.

2.1 Environment Preparation and Installation ​

Flue requires Node.js ≥ 22.19.0 and reuses all of Pi's Provider support — you only need the corresponding Provider API keys:

bash
# Check Node version (must be >= 22.19.0)
node --version

# Create project directory and initialize
mkdir my-flue-project && cd my-flue-project
npm init -y

# Install runtime and CLI
npm install @flue/runtime @flue/cli

Manage API keys with .env (never commit to git):

bash
# .env —— auto-loaded by Flue runtime
ANTHROPIC_API_KEY="sk-ant-xxx"
OPENAI_API_KEY="sk-xxx"

2.2 Project Configuration Files ​

Create flue.config.ts in the project root to declare the build target:

typescript
// flue.config.ts —— target determines which platform Flue generates code for
import { defineConfig } from '@flue/runtime/config';

export default defineConfig({
  target: 'node', // 'node' or 'cloudflare'
});

If deploying the agent as an HTTP service, you also need the Vite plugin and Hono server framework:

bash
npm install @flue/vite hono vite
typescript
// vite.config.ts —— the flue() plugin scans 'use agent' files
import { flue } from '@flue/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [flue()],
});

Bundle only the Providers you use

flue({ providers: ['anthropic', 'openai'] }) narrows built-in Providers to a whitelist; SDKs for unlisted Providers are completely excluded from the bundle — especially important for Cloudflare deployment package size.

2.3 Directory Structure Conventions ​

Recommended layout for a single-Agent project:

text
my-project/
├─ src/                  # Source directory (recommended)
│  ├─ app.ts             # Server route entry (required for deployment)
│  ├─ db.ts              # Database config (optional)
│  ├─ agents/            # Agent definitions
│  ├─ skills/            # Skills directory (SKILL.md)
│  ├─ tools/             # Tools directory
│  ├─ subagents/         # Sub-agent definitions
│  └─ channels/          # Event channels (Slack/GitHub etc.)
├─ package.json
├─ vite.config.ts        # Optional
└─ flue.config.ts        # Optional

The source directory selection order is .flue/ → src/ → project root. Flue does not merge multiple layouts: as long as .flue/ exists, all entries resolve from it. Larger projects can further subdivide by agent — each agent with its own skills/tools/subagents.

2.4 First Runnable Agent ​

Create src/agents/assistant.ts:

typescript
// src/agents/assistant.ts
'use agent'; // Must be at the top of the file, before any import
import { useModel } from '@flue/runtime';

export function Assistant() {
  // Declare the model powering this agent
  useModel('anthropic/claude-haiku-4-5');
  // Return value = system instructions
  return 'You are a helpful assistant. Keep replies short.';
}

Path A: CLI Local Run ​

The fastest way to verify — no server needed, direct conversation:

bash
# Single-turn conversation
npx flue run src/agents/assistant.ts --message "Say hello in five words or fewer."

# Multi-turn with --id: messages with the same ID share context
npx flue run src/agents/assistant.ts --id hello-1 --message "What's a good name for a pet crab?"
npx flue run src/agents/assistant.ts --id hello-1 --message "Give me three more."
# The second message picks up the first — sessions persist by ID

Path B: Vite Dev Server ​

First write the route entry src/app.ts (Hono app):

typescript
// src/app.ts —— fixed entry file for Flue apps
import { createAgentRouter } from '@flue/runtime/routing';
import { Hono } from 'hono';
import { Assistant } from './agents/assistant.ts';

const app = new Hono();
// Mount the agent at /agents/assistant route
app.route('/agents/assistant', createAgentRouter(Assistant));
export default app;

Start the dev server and send a message with curl:

bash
npx vite dev   # Listens on http://localhost:5173 by default

# Send a message: POST /agents/assistant/{id}, 202 means accepted
curl -X POST http://localhost:5173/agents/assistant/hello-1 \
  -H 'content-type: application/json' \
  -d '{"text": "Hello"}'

createAgentRouter() auto-generates a standard set of routes: POST /:id (send message), GET /:id (fetch session), POST /:id/abort (abort), etc.

2.5 Chapter Summary ​

  • Install @flue/runtime + @flue/cli; add @flue/vite + hono + vite for deployment;
  • flue.config.ts declares target; providers whitelist narrows bundle size;
  • Source directory order: .flue/ → src/ → root; mutually exclusive, not merged;
  • Two run paths: CLI direct run (debugging & CI) and vite dev + Hono routes (service deployment);
  • Sessions persist by agent ID; same ID across runs shares conversation context.

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. What is Flue's minimum required Node.js version?

2. Where should the "use agent" directive be placed?

3. When both .flue/ and src/ exist in a project, how does Flue choose the source directory?

4. What does the --id parameter of npx flue run do?

🛠️ Hands-On Exercises ​

  1. Complete steps 2.1–2.4; converse with your Assistant using both CLI and vite dev.
  2. Send three related messages with the same --id; verify the third remembers the first.
  3. Set providers: ['anthropic'] in the flue() plugin config; observe the build behavior change.

The project is running! Next, dive into Flue's core "use agent" programming model.