create-theokit 1.4.0 → 1.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-theokit",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "description": "Scaffold a new TheoKit project",
6
6
  "license": "Apache-2.0",
@@ -1,25 +1,20 @@
1
1
  import { agent } from '@theokit/agents'
2
2
  import { z } from 'zod'
3
3
 
4
- import { BASE_INSTRUCTIONS } from './_lib/instructions.js'
5
- import { weatherTool } from './_tools/weather.js'
4
+ import { BASE_INSTRUCTIONS } from './prompts/instructions.js'
5
+ import { weatherTool } from './tools/weather.js'
6
6
 
7
7
  /**
8
- * Chat agent — the zero-config `agents/*.ts` convention.
8
+ * The `chat` agent — served at `POST /api/agents/chat` and bound by `useAgent('chat')`. This file IS the
9
+ * agent; it composes its neighbours under `agents/`: the persona in `prompts/`, capabilities in `tools/`,
10
+ * procedures in `skills/`. Those folders are that concern, NOT extra routes — the framework's scanner
11
+ * treats `prompts/ tools/ skills/ lib/ …` as semantic folders, so `agents/tools/weather.ts` never becomes
12
+ * a `/api/agents/tools/weather` endpoint. Add a second agent as another `agents/<name>.ts`. See
13
+ * `docs/ARCHITECTURE.md`.
9
14
  *
10
- * This one file is auto-served at `POST /api/agents/chat` (dev + build), streaming the
11
- * ai-sdk `UIMessageStream` that `useAgent('chat')` consumes on the client. No manual route,
12
- * no manual client wiring. `@theokit/sdk` runs it; conversation turns auto-persist per
13
- * session (the SDK owns storage).
14
- *
15
- * Provider: resolved from the environment — OPENROUTER_API_KEY (preferred — gateway to many
16
- * models) OR ANTHROPIC_API_KEY / OPENAI_API_KEY. The `model` id is prefixed with the provider
17
- * namespace so OpenRouter routes it upstream (see https://openrouter.ai/models).
18
- *
19
- * The agent is composed from its neighbours (see `docs/ARCHITECTURE.md`): the persona lives in
20
- * `agents/_lib/instructions.ts` and tools in `agents/_tools/` (both underscore-prefixed so the
21
- * route scanner skips them). Add a tool with `tool('name')…build()` and chain it via `.tool(...)`;
22
- * add a skill as `agents/skills/<name>.md`.
15
+ * `@theokit/sdk` runs the agent; conversation turns auto-persist per session. Provider is resolved from
16
+ * the environment — OPENROUTER_API_KEY (preferred) OR ANTHROPIC_API_KEY / OPENAI_API_KEY; the model id is
17
+ * provider-prefixed so OpenRouter routes it upstream (https://openrouter.ai/models).
23
18
  */
24
19
  export default agent()
25
20
  .input(z.object({ message: z.string() }))
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The `chat` agent's system prompt (persona + rules). Lives in `prompts/` — a semantic sub-folder the
3
+ * framework's agent scanner skips, so it never becomes a route. Grow the persona here instead of inlining
4
+ * a long string in `index.ts`.
5
+ */
6
+ export const BASE_INSTRUCTIONS = `You are a helpful assistant living inside a TheoKit app.
7
+
8
+ - Answer clearly and concisely.
9
+ - When the user asks about current weather, call the \`weather\` tool instead of guessing.
10
+ - If you are unsure, say so rather than inventing an answer.`
@@ -1,20 +1,21 @@
1
1
  # Getting started
2
2
 
3
3
  A **skill** is a Markdown file that documents a repeatable task for your agent — a recipe it (and you) can
4
- follow. Skills live in `agents/skills/` and are plain `.md`, so the route scanner ignores them; reference
5
- them from your instructions or load them into a prompt as your app grows.
4
+ follow. Skills live in the agent's `skills/` folder and are plain `.md`; reference them from your prompt or
5
+ load them into context as your app grows.
6
6
 
7
- This example just documents the scaffold itself:
7
+ This example documents the scaffold itself:
8
8
 
9
9
  ## Answer a question
10
10
 
11
11
  1. Read the user's message.
12
- 2. If it needs live weather, call the `weather` tool (see `agents/_tools/weather.ts`).
12
+ 2. If it needs live weather, call the `weather` tool (see `../tools/weather.ts`).
13
13
  3. Otherwise answer directly, concisely.
14
14
 
15
- ## Add a capability
15
+ ## Add a capability to this agent
16
16
 
17
- - **A tool** (an action the agent can take) → `agents/_tools/<name>.ts`, then `.tool(<name>Tool)` in
17
+ - **A tool** (an action the agent can take) → `agents/tools/<name>.ts`, then `.tool(<name>Tool)` in
18
18
  `agents/chat.ts`.
19
19
  - **A skill** (a documented procedure) → a new `agents/skills/<name>.md` like this one.
20
- - **The persona / rules** → edit `agents/_lib/instructions.ts`.
20
+ - **The persona / rules** → edit `agents/prompts/instructions.ts`.
21
+ - **A whole new agent** → a new folder `agents/<name>/index.ts` → served at `/api/agents/<name>`.
@@ -5,8 +5,8 @@ import { z } from 'zod'
5
5
  * An example agent tool — current weather for a place, via the keyless open-meteo API.
6
6
  *
7
7
  * A tool is PURE metadata + a handler: it describes a capability and runs local/HTTP work; it NEVER calls
8
- * an LLM (the agent decides when to invoke it). Lives in `agents/_tools/` (underscore-prefixed) so the
9
- * route scanner skips it — it is imported into `agents/chat.ts` and chained with `.tool(weatherTool)`.
8
+ * an LLM (the agent decides when to invoke it). Lives in `tools/` — a semantic sub-folder the agent
9
+ * scanner skips — and is imported into `chat.ts` and chained with `.tool(weatherTool)`.
10
10
  *
11
11
  * Add your own the same way: `tool('name').describe(...).input(z.object({...})).execute(async (input) => …).build()`.
12
12
  */
@@ -1,18 +1,19 @@
1
1
  # Architecture
2
2
 
3
- How this TheoKit app is organized. The layout puts the **agent at the center** and keeps a clean split
4
- between the agent, the backend, the frontend, and cross-layer code.
3
+ How this TheoKit app is organized. The layout puts the **agent at the center**: the agent file and the
4
+ folders it composes (prompts, tools, skills) live together under `agents/`, with clean names — the
5
+ "file = identity" convention agent frameworks like [Eve](https://eve.dev) use.
5
6
 
6
7
  ## Project structure
7
8
 
8
9
  ```
9
10
  .
10
- ├── agents/ # The agent lives here (auto-served at POST /api/agents/<name>)
11
- │ ├── chat.ts # the agent — composed from its neighbours below
12
- │ ├── _lib/ # internal helpers (underscore = NOT a route)
13
- │ │ └── instructions.ts # the system prompt / persona
14
- │ ├── _tools/ # tools the agent can call (underscore = NOT a route)
15
- │ │ └── weather.ts # example: tool('weather')…build()
11
+ ├── agents/ # The agent, and what composes it
12
+ │ ├── chat.ts # the agent → POST /api/agents/chat, useAgent('chat')
13
+ │ ├── prompts/ # system prompts / personas
14
+ │ │ └── instructions.ts
15
+ │ ├── tools/ # tools the agent can call
16
+ │ │ └── weather.ts # tool('weather')…build()
16
17
  │ └── skills/ # Markdown procedures the agent (and you) can follow
17
18
  │ └── getting-started.md
18
19
  ├── app/ # Frontend (web surface). tui → tui/, desktop → frontend/
@@ -24,13 +25,14 @@ between the agent, the backend, the frontend, and cross-layer code.
24
25
  └── theo.config.ts # App config (name, dirs, plugins)
25
26
  ```
26
27
 
27
- ## Why `_lib/` and `_tools/` have an underscore
28
+ ## Clean names, no phantom routes
28
29
 
29
- The framework turns **every `.ts` under `agents/` into a `POST /api/agents/<name>` endpoint** (that is the
30
- zero-config convention that lets `useAgent('chat')` bind with no manual wiring). Files that are *not*
31
- agents — the persona, the tools — would otherwise become phantom endpoints, so they live in
32
- underscore-prefixed folders, which the route scanner skips (the same convention Next.js uses for private
33
- folders). `skills/` needs no underscore because Markdown is never scanned.
30
+ An agent is a file: `agents/<name>.ts` → `POST /api/agents/<name>`. But the framework's scanner is
31
+ **folder-semantic** — the conventional sub-folders under `agents/` (`prompts/`, `tools/`, `skills/`,
32
+ `lib/`, `hooks/`, `channels/`, `connections/`, `subagents/`, `schedules/`) are **that concern, not routes**.
33
+ So the names stay clean (`tools/`, not `_tools/`) and `agents/tools/weather.ts` never becomes a phantom
34
+ `/api/agents/tools/weather` endpoint. Markdown (`skills/*.md`) is never scanned either way. The
35
+ prompts/tools/skills are **shared** across every agent in `agents/`.
34
36
 
35
37
  ## Composition
36
38
 
@@ -40,13 +42,14 @@ folders). `skills/` needs no underscore because Markdown is never scanned.
40
42
  export default agent()
41
43
  .input(z.object({ message: z.string() }))
42
44
  .model('openai/gpt-4o-mini')
43
- .system(BASE_INSTRUCTIONS) // agents/_lib/instructions.ts
44
- .tool(weatherTool) // agents/_tools/weather.ts
45
+ .system(BASE_INSTRUCTIONS) // agents/prompts/instructions.ts
46
+ .tool(weatherTool) // agents/tools/weather.ts
45
47
  .build()
46
48
  ```
47
49
 
48
- Grow the agent by editing its neighbours, not by inflating `chat.ts`: persona → `_lib/instructions.ts`,
49
- a new capability → `_tools/<name>.ts` (then `.tool(<name>Tool)`), a documented procedure → `skills/<name>.md`.
50
+ Grow the agent by editing its neighbours, not by inflating `chat.ts`: persona → `prompts/instructions.ts`,
51
+ a new capability → `tools/<name>.ts` (then `.tool(<name>Tool)`), a documented procedure →
52
+ `skills/<name>.md`. Add a **second agent** as another `agents/<name>.ts`.
50
53
 
51
54
  ## Surfaces
52
55
 
@@ -5,18 +5,18 @@ Common changes, and where they go. See [ARCHITECTURE](./ARCHITECTURE.md) for the
5
5
  | I want to… | Edit |
6
6
  |------------|------|
7
7
  | Change the model | `agents/chat.ts` (`.model(...)`) + the label in `shared/agent.ts` |
8
- | Change the persona / rules | `agents/_lib/instructions.ts` |
9
- | Add a tool (an action the agent can take) | new `agents/_tools/<name>.ts`, then `.tool(<name>Tool)` in `agents/chat.ts` |
8
+ | Change the persona / rules | `agents/prompts/instructions.ts` |
9
+ | Add a tool (an action the agent can take) | new `agents/tools/<name>.ts`, then `.tool(<name>Tool)` in `agents/chat.ts` |
10
10
  | Add a skill (a documented procedure) | new `agents/skills/<name>.md` |
11
- | Change the greeting / app name | `shared/agent.ts` |
12
11
  | Add a second agent | new `agents/<name>.ts` → auto-served at `/api/agents/<name>`, bind with `useAgent('<name>')` |
12
+ | Change the greeting / app name | `shared/agent.ts` |
13
13
  | Add a backend route | `server/routes/<name>.ts` |
14
14
  | Change the provider key | `.env` — `OPENROUTER_API_KEY` (or `ANTHROPIC_API_KEY` / `OPENAI_API_KEY`). See [ENVIRONMENT](./ENVIRONMENT.md) |
15
15
 
16
16
  ## Adding a tool
17
17
 
18
18
  ```ts
19
- // agents/_tools/echo.ts
19
+ // agents/tools/echo.ts
20
20
  import { tool } from 'theokit/server'
21
21
  import { z } from 'zod'
22
22
 
@@ -29,7 +29,7 @@ export const echoTool = tool('echo')
29
29
 
30
30
  ```ts
31
31
  // agents/chat.ts
32
- import { echoTool } from './_tools/echo.js'
32
+ import { echoTool } from './tools/echo.js'
33
33
  // …
34
34
  .tool(weatherTool)
35
35
  .tool(echoTool) // chain as many as you need
@@ -15,7 +15,7 @@
15
15
  "typecheck": "tsc --noEmit"
16
16
  },
17
17
  "dependencies": {
18
- "theokit": "^0.30.3",
18
+ "theokit": "^0.31.0",
19
19
  "@theokit/agents": "^0.35.2",
20
20
  "@theokit/sdk": "^2.13.0",
21
21
  "@theokit/ui": "^1.0.0",
@@ -1,15 +0,0 @@
1
- /**
2
- * The agent's base system prompt.
3
- *
4
- * Kept in `agents/_lib/` (an underscore-prefixed folder) so the framework's `agents/*` route scanner
5
- * skips it — only real agents like `agents/chat.ts` become `POST /api/agents/<name>` endpoints. Import
6
- * this into an agent's `.system(...)`; grow it here (persona, guardrails, tool guidance) instead of
7
- * inlining a long string in the agent file.
8
- */
9
- import { AGENT } from '../../shared/agent.js'
10
-
11
- export const BASE_INSTRUCTIONS = `You are ${AGENT.name}, a helpful assistant living inside a TheoKit app.
12
-
13
- - Answer clearly and concisely.
14
- - When the user asks about current weather, call the \`weather\` tool instead of guessing.
15
- - If you are unsure, say so rather than inventing an answer.`