Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/skills-workspace-sources.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"agents": minor
---

Breaking: `agents/skills` now loads Agent Skills from Computer Workspace files (`workspace()`), R2 (`r2()`), or code (`manifest()`), checks `SKILL.md` against the Agent Skills spec, and replaces `SkillRegistry` with `loadSkillCatalog()` and `createSkillTools()` (from `agents/skills/tools/ai-sdk`); `parseSkill()` follows the spec's guide for agents, loading skills that break a rule with warnings; `runner()` moved to `agents/skills/runner`; the `agents:skills` Vite import and `agents/skills/compile` are removed. See [Agent Skills](https://developers.cloudflare.com/agents/skills/).
5 changes: 5 additions & 0 deletions .changeset/think-skills-from-files.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cloudflare/think": minor
---

Breaking: Think reloads `getSkills()` sources every turn, so `skills.workspace(this.workspace)` picks up skills written to `/workspace/.agents/skills`; an overridden `getSystemPrompt()` now always renders above context blocks instead of being dropped once any block exists; skill catalog changes reach the model as a context reminder rather than rebuilding the cached system prompt; `skillWorkspace` and the extension `"skill"` context block type are removed. See [Agent Skills](https://developers.cloudflare.com/agents/skills/).
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ The agent is a Durable Object, so it needs a binding and a SQLite migration in `
The [`examples/`](examples) directory has 30+ self-contained demos. A non-exhaustive tour:

- **Showcase** — [`playground/`](examples/playground) is the kitchen-sink app: state, callable methods, scheduling, chat, tools, MCP, workflows, email, voice — all in one UI
- **Chat & assistants** — [`assistant/`](examples/assistant), [`agents-as-tools/`](examples/agents-as-tools), [`agent-skills/`](examples/agent-skills), [`workspace-chat/`](examples/workspace-chat), [`resumable-stream-chat/`](examples/resumable-stream-chat), [`structured-input/`](examples/structured-input), [`dynamic-tools/`](examples/dynamic-tools), [`multi-ai-chat/`](examples/multi-ai-chat), [`context-overflow-recovery/`](examples/context-overflow-recovery)
- **Chat & assistants** — [`agents-as-tools/`](examples/agents-as-tools), [`computer-skills/`](examples/computer-skills), [`r2-skills/`](examples/r2-skills), [`workspace-chat/`](examples/workspace-chat), [`resumable-stream-chat/`](examples/resumable-stream-chat), [`structured-input/`](examples/structured-input), [`dynamic-tools/`](examples/dynamic-tools), [`multi-ai-chat/`](examples/multi-ai-chat), [`context-overflow-recovery/`](examples/context-overflow-recovery)
- **MCP** — [`mcp/`](examples/mcp), [`mcp-client/`](examples/mcp-client), [`mcp-server/`](examples/mcp-server), [`mcp-worker/`](examples/mcp-worker), [`mcp-worker-authenticated/`](examples/mcp-worker-authenticated), [`mcp-elicitation-mrtr/`](examples/mcp-elicitation-mrtr), [`mcp-elicitation/`](examples/mcp-elicitation), [`mcp-rpc-transport/`](examples/mcp-rpc-transport), [`webmcp/`](examples/webmcp), [`webmcp-react/`](examples/webmcp-react)
- **Code Mode & sandboxes** — [`codemode/`](examples/codemode), [`codemode-mcp/`](examples/codemode-mcp), [`codemode-mcp-openapi/`](examples/codemode-mcp-openapi), [`dynamic-workers/`](examples/dynamic-workers), [`dynamic-workers-playground/`](examples/dynamic-workers-playground), [`worker-bundler-playground/`](examples/worker-bundler-playground)
- **Voice** — [`voice-agent/`](examples/voice-agent) is the unified voice pipeline example with Workers AI, AssemblyAI, Telnyx, and ElevenLabs STT; [`voice-input/`](examples/voice-input) covers dictation; [`telnyx-voice-agent/`](examples/telnyx-voice-agent) covers phone transport; [`elevenlabs-starter/`](examples/elevenlabs-starter) covers broader ElevenLabs media APIs
Expand Down
5 changes: 1 addition & 4 deletions agent-think/src/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ export interface AgentThinkSubmissionStatus {

/**
* agent-think's identity and operating contract as a durable, read-only
* context block. Unlike getSystemPrompt(), this block remains present when
* Think adds its own skills catalog context.
* context block, rendered next to Think's own skills catalog context.
*/
export function agentThinkContext(
getContext: () => RunContext | null
Expand Down Expand Up @@ -163,8 +162,6 @@ export class ThinkAgent extends ThinkBase {
override storeMessages = true;
override storeTools = true;

override skillWorkspace = { root: "/workspace/.agents/skills" };

readonly #workspaceAgent: DurableObjectStub<WorkspaceAgent>;
#workspaceReady: Promise<RemoteWorkspace> | null = null;
#context: RunContext | null = null;
Expand Down
31 changes: 10 additions & 21 deletions agent-think/test/worker.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,17 @@
import { Think, type SkillSource } from "@cloudflare/think";
import { skills, Think, type SkillSource } from "@cloudflare/think";
import type { ContextConfig } from "agents/context";
import { agentThinkContext, type RunContext } from "../src/agent";

const promptTestSkillSource: SkillSource = {
const promptTestSkillSource: SkillSource = skills.manifest({
id: "agent-think-prompt-test",
fingerprint: "agent-think-prompt-test-v1",
async list() {
return [
{
name: "prompt-test",
description: "Verify agent-think prompt composition."
}
];
},
async load(name) {
return name === "prompt-test"
? {
name,
description: "Verify agent-think prompt composition.",
body: "Follow the prompt composition test procedure."
}
: null;
}
};
skills: [
{
name: "prompt-test",
description: "Verify agent-think prompt composition.",
body: "Follow the prompt composition test procedure."
}
]
});

export class AgentThinkPromptTestAgent extends Think<Env> {
#runContext: RunContext = {
Expand Down
2 changes: 1 addition & 1 deletion agent-think/wrangler.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
]
},

// Skills mounted read-only into every Workspace at /workspace/.agents.
// Skills served to the model through Think's R2 skill source.
// Seed with `npm run seed:r2` (uploads skills/**/SKILL.md under `.agents/`).
"r2_buckets": [
{
Expand Down
2 changes: 1 addition & 1 deletion design/rfc-sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Default inline reconstruction still produces a complete data URL for compatibili

Keep first-class Agent Skills in `agents/skills`, not in Sessions message storage. Prompt-level loadable context (`R2SkillProvider` and the `load_context` tool) is a separate, smaller thing and lives in `agents/context`.

Think projects resolved `SKILL.md` files into the active workspace so Computer or legacy Shell tools can read and edit them. Computer uses `/workspace/.agents/skills`; legacy Shell uses `/.agents/skills`.
Update: skills are now read directly from Workspace files (`skills.workspace()` over `/workspace/.agents/skills`) or from R2; Think no longer projects sources into the Workspace. See [skills.md](./skills.md).

The source remains responsible for discovery and initial content. Workspace files become authoritative for subsequent activation and resource reads. Source fingerprints avoid statting and rewriting unchanged files on every wake. Resources copy lazily when first requested rather than fanning out one R2 read per resource during startup.

Expand Down
Loading
Loading