create-theokit 1.5.0 → 1.6.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 +1 -1
- package/templates/default/agents/chat.ts +10 -0
- package/templates/default/agents/prompts/instructions.ts +14 -3
- package/templates/default/agents/skills/daily-briefing.ts +31 -0
- package/templates/default/agents/tools/current-time.ts +35 -0
- package/templates/default/docs/ARCHITECTURE.md +10 -5
- package/templates/default/docs/CUSTOMIZATION.md +1 -1
- package/templates/default/package.json.tmpl +3 -3
- package/templates/default/agents/skills/getting-started.md +0 -21
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { agent } from '@theokit/agents'
|
|
2
|
+
import { defineSkillReadTool } from '@theokit/sdk'
|
|
2
3
|
import { z } from 'zod'
|
|
3
4
|
|
|
4
5
|
import { BASE_INSTRUCTIONS } from './prompts/instructions.js'
|
|
6
|
+
import { dailyBriefingSkill } from './skills/daily-briefing.js'
|
|
7
|
+
import { currentTimeTool } from './tools/current-time.js'
|
|
5
8
|
import { weatherTool } from './tools/weather.js'
|
|
6
9
|
|
|
7
10
|
/**
|
|
@@ -21,4 +24,11 @@ export default agent()
|
|
|
21
24
|
.model('openai/gpt-4o-mini')
|
|
22
25
|
.system(BASE_INSTRUCTIONS)
|
|
23
26
|
.tool(weatherTool)
|
|
27
|
+
.tool(currentTimeTool)
|
|
28
|
+
// `.skills([...])` registers the code-defined skill: the SDK lists its name + description in a
|
|
29
|
+
// `<skills>` block in every system prompt (cheap), so the model KNOWS the skill exists.
|
|
30
|
+
.skills([dailyBriefingSkill])
|
|
31
|
+
// `defineSkillReadTool` then gives the model a `skill_read` tool to load the full body on demand —
|
|
32
|
+
// so a long procedure only enters the prompt when the model actually needs it.
|
|
33
|
+
.tool(defineSkillReadTool([dailyBriefingSkill]))
|
|
24
34
|
.build()
|
|
@@ -5,6 +5,17 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export const BASE_INSTRUCTIONS = `You are a helpful assistant living inside a TheoKit app.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
- If you are unsure, say so rather than inventing an answer
|
|
8
|
+
## Voice
|
|
9
|
+
- Answer clearly and concisely. Prefer a direct answer over a preamble.
|
|
10
|
+
- If you are unsure, say so rather than inventing an answer.
|
|
11
|
+
|
|
12
|
+
## Tools — call them, don't guess
|
|
13
|
+
- **Current weather** for a place → call the \`weather\` tool.
|
|
14
|
+
- **Current date / time** (optionally for a timezone) → call the \`current_time\` tool.
|
|
15
|
+
- Never state a time or the weather from memory; always call the tool. If a tool errors, tell the user
|
|
16
|
+
what failed and what you need (e.g. a valid city or IANA timezone).
|
|
17
|
+
|
|
18
|
+
## Skills
|
|
19
|
+
- The \`<skills>\` block above lists documented procedures (skills) by name + description. When a request
|
|
20
|
+
matches a skill's description, call the \`skill_read\` tool with that skill's name to load its full
|
|
21
|
+
steps, then follow them. Don't guess a procedure a skill already documents.`
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createSkill } from '@theokit/sdk'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A real, code-defined skill (`createSkill`) — a documented procedure the MODEL can pull in on demand.
|
|
5
|
+
*
|
|
6
|
+
* Unlike a loose Markdown note, this is wired into the agent: `agents/chat.ts` passes it to
|
|
7
|
+
* `defineSkillReadTool([...])`, which gives the model a `skill_read` tool. The model sees the skill's
|
|
8
|
+
* name + description in every turn (cheap) and calls `skill_read('daily-briefing')` to load the full
|
|
9
|
+
* `instructions` only when it actually needs them — so long procedures don't bloat every prompt.
|
|
10
|
+
*
|
|
11
|
+
* Lives in `agents/skills/` — a semantic folder the route scanner skips, so it never becomes an endpoint.
|
|
12
|
+
*/
|
|
13
|
+
export const dailyBriefingSkill = createSkill({
|
|
14
|
+
name: 'daily-briefing',
|
|
15
|
+
description:
|
|
16
|
+
"Produce a short 'good morning' briefing (today's date, the weather, and a one-line nudge).",
|
|
17
|
+
instructions: `# Daily briefing
|
|
18
|
+
|
|
19
|
+
Trigger: the user asks for a "briefing", "morning update", or "what's my day looking like".
|
|
20
|
+
|
|
21
|
+
Steps:
|
|
22
|
+
1. Ask for (or reuse) the user's city and IANA timezone if you don't already have them.
|
|
23
|
+
2. Call the \`current_time\` tool with their timezone → the local date and time.
|
|
24
|
+
3. Call the \`weather\` tool with their city → the current conditions.
|
|
25
|
+
4. Reply in exactly three lines:
|
|
26
|
+
- **Today** — weekday + date (from current_time).
|
|
27
|
+
- **Weather** — conditions + temperature (from weather).
|
|
28
|
+
- **Nudge** — one short, friendly suggestion based on the weather.
|
|
29
|
+
|
|
30
|
+
Never invent the time or weather — always call the tools. Keep it to three lines unless asked for more.`,
|
|
31
|
+
})
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { tool } from 'theokit/server'
|
|
2
|
+
import { z } from 'zod'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A local, deterministic tool — the current date + time, optionally in an IANA timezone. No network,
|
|
6
|
+
* always works: the counterpart to `weather.ts` (which hits an HTTP API), so the scaffold shows both a
|
|
7
|
+
* remote-call tool and a pure local one. Imported into `chat.ts` and chained with `.tool(currentTimeTool)`.
|
|
8
|
+
*/
|
|
9
|
+
export const currentTimeTool = tool('current_time')
|
|
10
|
+
.describe('Get the current date and time, optionally for a specific IANA timezone.')
|
|
11
|
+
.input(
|
|
12
|
+
z.object({
|
|
13
|
+
timezone: z
|
|
14
|
+
.string()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe('IANA timezone, e.g. "Europe/Lisbon" or "America/Sao_Paulo". Defaults to UTC.'),
|
|
17
|
+
}),
|
|
18
|
+
)
|
|
19
|
+
.execute(async ({ timezone }) => {
|
|
20
|
+
const tz = timezone ?? 'UTC'
|
|
21
|
+
try {
|
|
22
|
+
const formatted = new Intl.DateTimeFormat('en-US', {
|
|
23
|
+
timeZone: tz,
|
|
24
|
+
dateStyle: 'full',
|
|
25
|
+
timeStyle: 'long',
|
|
26
|
+
}).format(new Date())
|
|
27
|
+
return `Current time (${tz}): ${formatted}`
|
|
28
|
+
} catch {
|
|
29
|
+
// fail-fast with a clear, actionable message (Rule 8) rather than a cryptic RangeError.
|
|
30
|
+
throw new Error(
|
|
31
|
+
`Unknown timezone "${tz}". Use an IANA name like "Europe/Lisbon" or "America/Sao_Paulo".`,
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
.build()
|
|
@@ -13,9 +13,10 @@ folders it composes (prompts, tools, skills) live together under `agents/`, with
|
|
|
13
13
|
│ ├── prompts/ # system prompts / personas
|
|
14
14
|
│ │ └── instructions.ts
|
|
15
15
|
│ ├── tools/ # tools the agent can call
|
|
16
|
-
│ │
|
|
17
|
-
│ └──
|
|
18
|
-
│
|
|
16
|
+
│ │ ├── weather.ts # remote — current weather via open-meteo (HTTP)
|
|
17
|
+
│ │ └── current-time.ts # local — date/time in an IANA timezone (no network)
|
|
18
|
+
│ └── skills/ # procedures the model loads on demand (createSkill)
|
|
19
|
+
│ └── daily-briefing.ts # a real skill: time → weather → a one-line nudge
|
|
19
20
|
├── app/ # Frontend (web surface). tui → tui/, desktop → frontend/
|
|
20
21
|
├── server/ # Backend routes / actions (POST/GET handlers, jobs)
|
|
21
22
|
├── shared/ # Code imported by more than one layer
|
|
@@ -44,12 +45,16 @@ export default agent()
|
|
|
44
45
|
.model('openai/gpt-4o-mini')
|
|
45
46
|
.system(BASE_INSTRUCTIONS) // agents/prompts/instructions.ts
|
|
46
47
|
.tool(weatherTool) // agents/tools/weather.ts
|
|
48
|
+
.tool(currentTimeTool) // agents/tools/current-time.ts
|
|
49
|
+
.tool(defineSkillReadTool([dailyBriefingSkill])) // agents/skills/daily-briefing.ts
|
|
47
50
|
.build()
|
|
48
51
|
```
|
|
49
52
|
|
|
50
53
|
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>.
|
|
54
|
+
a new capability → `tools/<name>.ts` (then `.tool(<name>Tool)`), a documented procedure → a
|
|
55
|
+
`createSkill(...)` in `skills/<name>.ts` (add it to the `defineSkillReadTool([...])` list). A **skill** is
|
|
56
|
+
loaded by the model on demand via the `skill_read` tool, so long procedures don't bloat every prompt. Add a
|
|
57
|
+
**second agent** as another `agents/<name>.ts`.
|
|
53
58
|
|
|
54
59
|
## Surfaces
|
|
55
60
|
|
|
@@ -7,7 +7,7 @@ Common changes, and where they go. See [ARCHITECTURE](./ARCHITECTURE.md) for the
|
|
|
7
7
|
| Change the model | `agents/chat.ts` (`.model(...)`) + the label in `shared/agent.ts` |
|
|
8
8
|
| Change the persona / rules | `agents/prompts/instructions.ts` |
|
|
9
9
|
| Add a tool (an action the agent can take) | new `agents/tools/<name>.ts`, then `.tool(<name>Tool)` in `agents/chat.ts` |
|
|
10
|
-
| Add a skill (a
|
|
10
|
+
| Add a skill (a procedure the model loads on demand) | `createSkill(...)` in `agents/skills/<name>.ts`, then add it to `defineSkillReadTool([...])` in `agents/chat.ts` |
|
|
11
11
|
| Add a second agent | new `agents/<name>.ts` → auto-served at `/api/agents/<name>`, bind with `useAgent('<name>')` |
|
|
12
12
|
| Change the greeting / app name | `shared/agent.ts` |
|
|
13
13
|
| Add a backend route | `server/routes/<name>.ts` |
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"typecheck": "tsc --noEmit"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"theokit": "^0.
|
|
19
|
-
"@theokit/agents": "^0.
|
|
20
|
-
"@theokit/sdk": "^2.
|
|
18
|
+
"theokit": "^0.35.0",
|
|
19
|
+
"@theokit/agents": "^0.37.0",
|
|
20
|
+
"@theokit/sdk": "^2.25.0",
|
|
21
21
|
"@theokit/ui": "^1.0.0",
|
|
22
22
|
"@usetheo/ui": "^0.14.0",
|
|
23
23
|
"ai": "^7.0.0",
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# Getting started
|
|
2
|
-
|
|
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 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
|
-
|
|
7
|
-
This example documents the scaffold itself:
|
|
8
|
-
|
|
9
|
-
## Answer a question
|
|
10
|
-
|
|
11
|
-
1. Read the user's message.
|
|
12
|
-
2. If it needs live weather, call the `weather` tool (see `../tools/weather.ts`).
|
|
13
|
-
3. Otherwise answer directly, concisely.
|
|
14
|
-
|
|
15
|
-
## Add a capability to this agent
|
|
16
|
-
|
|
17
|
-
- **A tool** (an action the agent can take) → `agents/tools/<name>.ts`, then `.tool(<name>Tool)` in
|
|
18
|
-
`agents/chat.ts`.
|
|
19
|
-
- **A skill** (a documented procedure) → a new `agents/skills/<name>.md` like this one.
|
|
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>`.
|