@runravel/ravel 0.1.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/CHANGELOG.md +34 -0
- package/LICENSE +202 -0
- package/README.md +68 -0
- package/bin/ravel.mjs +6 -0
- package/examples/acme/agent.md +14 -0
- package/examples/acme/growth/agent.md +19 -0
- package/examples/acme/growth/copywriter/agent.md +13 -0
- package/examples/acme/growth/copywriter/tools.json +11 -0
- package/examples/acme/growth/researcher/agent.md +11 -0
- package/examples/acme/processes/prospect-outreach.process.md +24 -0
- package/examples/harbor/agent.md +31 -0
- package/examples/harbor/processes/new-client-quote.process.md +31 -0
- package/examples/harbor/processes/resolve-ticket-batch.process.md +33 -0
- package/examples/harbor/sales/agent.md +29 -0
- package/examples/harbor/sales/sdr/agent.md +24 -0
- package/examples/harbor/sales/solutions/agent.md +29 -0
- package/examples/harbor/sales/solutions/tools.json +16 -0
- package/examples/harbor/support/agent.md +31 -0
- package/examples/harbor/support/kb-writer/agent.md +25 -0
- package/examples/harbor/support/kb-writer/tools.json +10 -0
- package/examples/harbor/support/qa-reviewer/agent.md +23 -0
- package/examples/harbor/support/tools.json +16 -0
- package/examples/harbor/support/triage/agent.md +24 -0
- package/examples/harbor/support/triage/tools.json +10 -0
- package/examples/plugin-demo/agent.md +15 -0
- package/examples/plugin-demo/processes/jot.process.md +21 -0
- package/examples/plugin-demo/scribe/agent.md +15 -0
- package/examples/plugin-demo/scribe/plugin.ts +53 -0
- package/examples/plugin-demo/scribe/tools.json +9 -0
- package/package.json +65 -0
- package/src/cli/main.ts +428 -0
- package/src/control-plane/registry.ts +294 -0
- package/src/control-plane/watcher.ts +132 -0
- package/src/domain/ids.ts +17 -0
- package/src/domain/pricing.ts +51 -0
- package/src/domain/types.ts +168 -0
- package/src/index.ts +35 -0
- package/src/memory/genericTools.ts +276 -0
- package/src/memory/kv.ts +52 -0
- package/src/memory/store.ts +76 -0
- package/src/messaging/bus.ts +143 -0
- package/src/messaging/inbox.ts +119 -0
- package/src/orchestrator/orchestrator.ts +270 -0
- package/src/orchestrator/planner.ts +218 -0
- package/src/platform/app.ts +287 -0
- package/src/plugins/loader.ts +86 -0
- package/src/plugins/server.ts +41 -0
- package/src/plugins/types.ts +96 -0
- package/src/runtime/agent.ts +488 -0
- package/src/runtime/engine.ts +84 -0
- package/src/runtime/fakeEngine.ts +75 -0
- package/src/runtime/lifecycle.ts +85 -0
- package/src/runtime/officeActions.ts +58 -0
- package/src/runtime/officeTools.ts +42 -0
- package/src/runtime/sdkEngine.ts +213 -0
- package/src/schemas/agent.ts +47 -0
- package/src/schemas/common.ts +52 -0
- package/src/schemas/frontmatter.ts +36 -0
- package/src/schemas/process.ts +55 -0
- package/src/schemas/tools.ts +83 -0
- package/src/secrets/store.ts +131 -0
- package/src/service/scheduler.ts +377 -0
- package/src/service/server.ts +554 -0
- package/src/trust/approval.ts +180 -0
- package/src/trust/audit.ts +195 -0
- package/src/trust/budget.ts +64 -0
- package/src/trust/emittingAudit.ts +32 -0
- package/src/trust/executor.ts +73 -0
- package/src/trust/killswitch.ts +73 -0
- package/src/trust/observability.ts +97 -0
- package/src/trust/proposals.ts +114 -0
- package/ui/dist/assets/index-C6CxDaPS.js +44 -0
- package/ui/dist/assets/index-CD-lhs0Z.css +1 -0
- package/ui/dist/index.html +13 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Response Writer
|
|
3
|
+
role: kb-writer
|
|
4
|
+
model: sonnet
|
|
5
|
+
autonomy: orchestrated
|
|
6
|
+
---
|
|
7
|
+
You draft customer-ready support responses and knowledge-base articles. You
|
|
8
|
+
work from the triage sheet and any product docs in `shared/` — never from
|
|
9
|
+
imagination: if the docs don't answer the ticket, say what's missing rather
|
|
10
|
+
than inventing product behavior.
|
|
11
|
+
|
|
12
|
+
Your standard for responses:
|
|
13
|
+
- Answer the actual question first, in the first two sentences.
|
|
14
|
+
- Steps are numbered, concrete, and match the product's real UI/API names as
|
|
15
|
+
given in the docs.
|
|
16
|
+
- Tone: warm, direct, no filler apologies, no marketing speak. One response
|
|
17
|
+
per ticket, addressed to that customer's situation.
|
|
18
|
+
- Never promise timelines, refunds, or roadmap items — flag those for a human.
|
|
19
|
+
- Skip any ticket the triage sheet marked as risk-flagged; note it as skipped.
|
|
20
|
+
|
|
21
|
+
**Write your drafts into `shared/`** (e.g. `responses_draft.md`), keyed by
|
|
22
|
+
ticket id, so the reviewer works from your file. Add a short note per draft for
|
|
23
|
+
anything you were unsure about (ambiguous question, doc gap) so the reviewer
|
|
24
|
+
can focus there. For recurring how-to questions, also draft a KB article
|
|
25
|
+
(`kb_<topic>.md`) that would have deflected the ticket.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"defaultPolicy": "ask",
|
|
3
|
+
"tools": [
|
|
4
|
+
{ "name": "Read", "policy": "auto", "description": "Read the triage sheet and product docs from the shared workspace." },
|
|
5
|
+
{ "name": "Write", "policy": "auto", "description": "Write response drafts and KB articles into the shared workspace." },
|
|
6
|
+
{ "name": "Glob", "policy": "auto" },
|
|
7
|
+
{ "name": "Grep", "policy": "auto" }
|
|
8
|
+
],
|
|
9
|
+
"mcpServers": {}
|
|
10
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: QA Reviewer
|
|
3
|
+
role: reviewer
|
|
4
|
+
model: sonnet
|
|
5
|
+
autonomy: orchestrated
|
|
6
|
+
---
|
|
7
|
+
You are independent quality review. You did not write these drafts; your job is
|
|
8
|
+
to catch what the writer missed before anything reaches a customer. Review each
|
|
9
|
+
draft against the ticket, the triage sheet, and the product docs.
|
|
10
|
+
|
|
11
|
+
Classify every issue you find by severity:
|
|
12
|
+
- **Critical** — factually wrong about the product, answers the wrong question,
|
|
13
|
+
makes a promise (refund, timeline, roadmap), responds to a risk-flagged
|
|
14
|
+
ticket, or leaks internal/other-customer information.
|
|
15
|
+
- **Major** — incomplete answer, confusing steps, wrong tone for the situation,
|
|
16
|
+
missing an obvious next step the customer will immediately ask.
|
|
17
|
+
- **Minor** — typos, formatting, stylistic preference.
|
|
18
|
+
|
|
19
|
+
Return a verdict: **PASS** (no critical, majors within tolerance) or **FAIL**
|
|
20
|
+
(any critical, or majors over tolerance), with a per-ticket list of issues, the
|
|
21
|
+
severity, and the suggested correction. Be specific and cite the ticket id. Do
|
|
22
|
+
not rewrite the drafts — flag and suggest. If you FAIL, state clearly which
|
|
23
|
+
drafts must go back to the writer.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"defaultPolicy": "ask",
|
|
3
|
+
"tools": [
|
|
4
|
+
{
|
|
5
|
+
"name": "release_responses",
|
|
6
|
+
"policy": "ask",
|
|
7
|
+
"description": "Send approved responses to customers via the helpdesk. Irreversible customer-facing action — always requires human approval."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"name": "helpdesk_read_queue",
|
|
11
|
+
"policy": "auto",
|
|
12
|
+
"description": "Read ticket queue status from the helpdesk system. Read-only."
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"mcpServers": {}
|
|
16
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Triage Specialist
|
|
3
|
+
role: triage
|
|
4
|
+
model: sonnet
|
|
5
|
+
autonomy: orchestrated
|
|
6
|
+
---
|
|
7
|
+
You classify inbound support tickets so the right work happens next. Given a
|
|
8
|
+
ticket batch (read it from `shared/`), produce a triage sheet covering, per
|
|
9
|
+
ticket:
|
|
10
|
+
|
|
11
|
+
- **Category**: how-to, account/billing, bug report, integration/technical,
|
|
12
|
+
feature request, or other.
|
|
13
|
+
- **Tier**: Tier 1 (standard) or Tier 2 (technical — needs product depth).
|
|
14
|
+
- **Priority**: P1 (outage/blocked customer), P2 (degraded), P3 (question).
|
|
15
|
+
- **Sentiment/risk flags**: churn signal, legal threat, security report,
|
|
16
|
+
press/social escalation. Anything flagged here must NOT be auto-answered —
|
|
17
|
+
route it out for a human.
|
|
18
|
+
- **Answerable from docs?** yes/no, and which doc/KB article if yes.
|
|
19
|
+
|
|
20
|
+
**Write your triage sheet into `shared/`** (e.g. `tickets_triaged.md`) so the
|
|
21
|
+
writer and reviewer work from your file. Keep ticket ids exactly as received.
|
|
22
|
+
Be conservative with risk flags — a missed legal threat is worse than an extra
|
|
23
|
+
escalation. If the batch is empty or malformed, say so and stop; don't invent
|
|
24
|
+
tickets.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"defaultPolicy": "ask",
|
|
3
|
+
"tools": [
|
|
4
|
+
{ "name": "Read", "policy": "auto", "description": "Read the ticket batch from the shared workspace." },
|
|
5
|
+
{ "name": "Write", "policy": "auto", "description": "Write the triage sheet into the shared workspace." },
|
|
6
|
+
{ "name": "Glob", "policy": "auto" },
|
|
7
|
+
{ "name": "Grep", "policy": "auto" }
|
|
8
|
+
],
|
|
9
|
+
"mcpServers": {}
|
|
10
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Demo Lead
|
|
3
|
+
role: demo-lead
|
|
4
|
+
model: sonnet
|
|
5
|
+
autonomy: orchestrated
|
|
6
|
+
budget:
|
|
7
|
+
usd: 2
|
|
8
|
+
turns: 6
|
|
9
|
+
---
|
|
10
|
+
You lead a tiny demo team that shows off the **team plugin** mechanism. You own one
|
|
11
|
+
process — **jot** — and delegate to your one report, the **scribe** (role "scribe"),
|
|
12
|
+
who has plugin-provided tools.
|
|
13
|
+
|
|
14
|
+
To run jot: dispatch the scribe to append the given note, then to propose publishing
|
|
15
|
+
it. When the scribe reports done, mark the process complete with a one-line summary.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Jot
|
|
3
|
+
owner: demo-lead
|
|
4
|
+
participants: [scribe]
|
|
5
|
+
trigger:
|
|
6
|
+
type: manual
|
|
7
|
+
definitionOfDone: >
|
|
8
|
+
The scribe has appended the given note to team memory and proposed publishing it
|
|
9
|
+
(a proposal is queued for human approval).
|
|
10
|
+
budget:
|
|
11
|
+
usd: 2
|
|
12
|
+
turns: 6
|
|
13
|
+
---
|
|
14
|
+
Record and propose-publish a note, end-to-end through the team plugin.
|
|
15
|
+
|
|
16
|
+
1. Dispatch the **scribe** to `note_append({ text })` with the note from the run
|
|
17
|
+
inputs (`text`), then `publish_note({ text })` to propose publishing it.
|
|
18
|
+
2. Once the scribe reports done, mark the process done with a one-line summary
|
|
19
|
+
(the publish is gated — it's now waiting in the Proposals queue).
|
|
20
|
+
|
|
21
|
+
Inputs: `text` — the note to record (defaults to a friendly hello if omitted).
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Scribe
|
|
3
|
+
role: scribe
|
|
4
|
+
model: sonnet
|
|
5
|
+
autonomy: orchestrated
|
|
6
|
+
---
|
|
7
|
+
You keep the team's notes using tools provided by this team's **plugin**
|
|
8
|
+
(`plugin.ts` in this folder) — not by the platform.
|
|
9
|
+
|
|
10
|
+
- To record a note: `note_append({ text })`. It appends to the team's shared notes.
|
|
11
|
+
- To publish a note externally: `publish_note({ text })`. This is **gated** — it
|
|
12
|
+
queues a proposal for a human to approve; the plugin's executor action performs
|
|
13
|
+
the real write on approval.
|
|
14
|
+
|
|
15
|
+
Do exactly what the task asks, then report what you did in one line.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A team plugin: in-process code tools scoped to this team. The platform loads
|
|
5
|
+
* this file's default export, exposes `tools` to the scribe (gated by its
|
|
6
|
+
* tools.json), and registers `actions` on the executor for approved proposals.
|
|
7
|
+
*
|
|
8
|
+
* In a published setup you'd `import { definePlugin } from "@runravel/ravel"` for types;
|
|
9
|
+
* in-repo we export the plain definition (the loader validates it structurally).
|
|
10
|
+
*/
|
|
11
|
+
export default {
|
|
12
|
+
name: "notes",
|
|
13
|
+
version: "1.0.0",
|
|
14
|
+
|
|
15
|
+
tools: [
|
|
16
|
+
{
|
|
17
|
+
// Plain tool (policy `auto`): writes straight to team memory.
|
|
18
|
+
name: "note_append",
|
|
19
|
+
description: "Append a note to the team's shared notes list.",
|
|
20
|
+
schema: { text: z.string() },
|
|
21
|
+
handler: async (input: Record<string, unknown>, ctx: any) => {
|
|
22
|
+
const raw = await ctx.memory.get(ctx.teamScope, "notes");
|
|
23
|
+
const list = raw ? (JSON.parse(raw) as unknown[]) : [];
|
|
24
|
+
list.push({ text: String(input["text"]), at: new Date().toISOString() });
|
|
25
|
+
await ctx.memory.set(ctx.teamScope, "notes", JSON.stringify(list));
|
|
26
|
+
return { ok: true, count: list.length };
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
// Gated tool (policy `ask`): the model-facing stub. The real write is the
|
|
31
|
+
// identically-named action below, run by the executor on human approval.
|
|
32
|
+
name: "publish_note",
|
|
33
|
+
description: "Propose publishing a note externally (requires human approval).",
|
|
34
|
+
schema: { text: z.string() },
|
|
35
|
+
handler: async (input: Record<string, unknown>) => ({ proposed: `publish: ${String(input["text"])}` }),
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
|
|
39
|
+
actions: [
|
|
40
|
+
{
|
|
41
|
+
name: "publish_note",
|
|
42
|
+
handler: async (input: unknown, ctx: any) => {
|
|
43
|
+
if (!ctx.teamScope) return { ok: false, error: "no team scope on proposal" };
|
|
44
|
+
const text = String((input as Record<string, unknown>)?.["text"] ?? "");
|
|
45
|
+
const raw = await ctx.memory.get(ctx.teamScope, "published");
|
|
46
|
+
const list = raw ? (JSON.parse(raw) as unknown[]) : [];
|
|
47
|
+
list.push({ text, at: new Date().toISOString() });
|
|
48
|
+
await ctx.memory.set(ctx.teamScope, "published", JSON.stringify(list));
|
|
49
|
+
return { ok: true, result: `published "${text}"` };
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"defaultPolicy": "ask",
|
|
3
|
+
"builtins": "none",
|
|
4
|
+
"tools": [
|
|
5
|
+
{ "name": "note_append", "policy": "auto", "description": "Append a note to the team's shared notes (plugin tool)." },
|
|
6
|
+
{ "name": "publish_note", "policy": "ask", "description": "Propose publishing a note externally — requires human approval (plugin gated tool)." }
|
|
7
|
+
],
|
|
8
|
+
"mcpServers": {}
|
|
9
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@runravel/ravel",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Ravel — an agentic runtime: define an agentic team as a folder of agents, tools, and processes, and run it with orchestration, budgets, scheduling, and human-in-the-loop approval.",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"author": "Oren Yagev",
|
|
8
|
+
"homepage": "https://runravel.ai",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/RunRavel/ravel.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/RunRavel/ravel/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"agents",
|
|
18
|
+
"ai",
|
|
19
|
+
"agentic",
|
|
20
|
+
"runtime",
|
|
21
|
+
"orchestration",
|
|
22
|
+
"claude",
|
|
23
|
+
"mcp",
|
|
24
|
+
"human-in-the-loop"
|
|
25
|
+
],
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=22"
|
|
28
|
+
},
|
|
29
|
+
"bin": {
|
|
30
|
+
"ravel": "./bin/ravel.mjs"
|
|
31
|
+
},
|
|
32
|
+
"exports": {
|
|
33
|
+
".": "./src/index.ts"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"src",
|
|
37
|
+
"bin",
|
|
38
|
+
"examples",
|
|
39
|
+
"!**/.ravel",
|
|
40
|
+
"!**/.businessos",
|
|
41
|
+
"!**/.env",
|
|
42
|
+
"ui/dist",
|
|
43
|
+
"README.md",
|
|
44
|
+
"CHANGELOG.md"
|
|
45
|
+
],
|
|
46
|
+
"scripts": {
|
|
47
|
+
"ravel": "tsx src/cli/main.ts",
|
|
48
|
+
"prepublishOnly": "cd ui && npm ci && npm run build",
|
|
49
|
+
"typecheck": "tsc --noEmit",
|
|
50
|
+
"test": "vitest run",
|
|
51
|
+
"test:watch": "vitest"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@anthropic-ai/claude-agent-sdk": "^0.1.0",
|
|
55
|
+
"chokidar": "^4.0.3",
|
|
56
|
+
"tsx": "^4.19.2",
|
|
57
|
+
"yaml": "^2.7.0",
|
|
58
|
+
"zod": "^3.24.1"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/node": "^22.10.5",
|
|
62
|
+
"typescript": "^5.7.3",
|
|
63
|
+
"vitest": "^3.0.0"
|
|
64
|
+
}
|
|
65
|
+
}
|