Skip to content
Open
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
47 changes: 47 additions & 0 deletions examples/vc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Venture capital tenant package

A tenant package for a venture fund, shaped the same way as [`examples/fintech`](../fintech):
five YAML files that describe the coworkers a deployment ships with, the channels they answer in,
the model behind them, and where authorized knowledge is read from. It is configuration, not code.

Point a deployment at it with `TENANT_PACKAGE_DIR`, resolved from `server/`:

```sh
TENANT_PACKAGE_DIR=../examples/vc bash scripts/start.sh
```

## Coworkers

| Coworker | Type | Does |
| ------------------- | ------------- | --------------------------------------------------------------------- |
| Deal Scout | built-in | Screens inbound decks and intros, briefs them against the thesis. |
| Diligence Analyst | remote-ag-ui | First-pass market and company diligence on a governed computer. |
| Portfolio Monitor | built-in | Tracks portfolio news, updates, and distress signals. |
| Fund Knowledge | built-in | Answers from thesis, memos, and prior deals, with sources. |
| LP Relations | built-in | Drafts LP updates and answers from authorized fund data. |

Deal Scout, Portfolio Monitor, Fund Knowledge, and LP Relations are `built-in`: a system prompt and
nothing else. Diligence Analyst is `remote-ag-ui`, so it drives a real browser on its own governed
computer — market sizing, founder and competitor research, red-flag checks — and can hand the wheel
to a person when it reaches a login wall or a check it should not clear alone. Its endpoint is read
from `MANAGED_AGENT_AG_UI_URL`, falling back to the Bot in the box so a clone runs with no
configuration. Swap it for a diligence agent of your own — on any framework, over AG-UI — and
nothing else here changes.

## Channels and groups

`channels.yaml` opens each coworker to a set of groups: `partners`, `investment`, and `platform` in
this example. Deal flow, diligence, and LP relations are scoped tighter than portfolio tracking and
fund knowledge. Map these names to your own directory groups, and remember that access to knowledge,
credentials, and browser actions is still governed at `/admin/boundaries` and `/admin/credentials` —
the channel decides who can talk to a coworker, not what it is allowed to do.

## Before you rely on it

- The knowledge roots (`Deals`, `Portfolio`, `Thesis`, `LP`, `Fund Operations`) are folder names to
replace with your own. Connect the sources at `/admin/connectors`.
- Keep deal terms, LP identities, and portfolio figures in governed knowledge and credentials, never
in this YAML. The prompts tell each coworker to cite sources and to refuse to invent figures, but
the boundary is what enforces it.
- Add a `theme.css` beside these files to reskin the surface; see
[docs/configuration.md](../../docs/configuration.md).
81 changes: 81 additions & 0 deletions examples/vc/agents.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# A tenant package for a venture capital fund. Every Bot here is reachable the moment the deployment
# starts, so the surface never registers an endpoint that is unavailable by default.
#
# The coworkers below are configuration, not code. Edit their prompts, add your own, or point one at
# a framework Bot of your own by giving it an `endpoint`. Keep the browser-driving roles governed:
# what a Bot may open, read, and type is decided at /admin/boundaries, not here.
agents:
# Reads inbound decks and forwarded intros and turns them into a short, comparable brief: what the
# company does, stage, round, traction claims, and how it sits against the fund's thesis. It reasons
# over what it is given and cites the fund's own memos; it does not browse.
- id: deal-scout
name: Deal Scout
title: Inbound & Screening
role_description: Triage inbound decks and intros, and brief them against the fund thesis.
avatar_seed: deal-scout
type: built-in
system_prompt: >-
You screen inbound venture deals for a fund. For each company, produce a concise, comparable
brief: what it does in one line, stage and round, the traction and metrics claimed, the team,
and the clearest risks. Judge fit against the fund's thesis and prior memos from authorized
knowledge, and cite every source you use. Never invent metrics, funding amounts, or investor
names: if a figure is not in what you were given, say it is not stated. Separate what the
founder claims from what is verified. End with a recommendation to pass, watch, or advance, and
the single most important open question a partner should ask.

# Does the reading a first-pass diligence needs, on its own governed computer: founder and company
# background, market size, the competitive set, news and any red flags. It has a real browser, so it
# can reach a login wall or a check it should not clear alone and hand the wheel back to a person.
# Named in dollar-brace form so the address belongs to the deployment; the fallback points at the
# Bot in the box, so a clone runs with no configuration.
- id: diligence-analyst
name: Diligence Analyst
title: Market & Company Diligence
role_description: Run first-pass diligence on a company, its market, and its competitors.
avatar_seed: diligence-analyst
type: remote-ag-ui
endpoint: ${MANAGED_AGENT_AG_UI_URL:-http://localhost:4200/ag-ui}

# Watches the portfolio: funding, hiring, launches, press, and anything that looks like distress.
# Answers from authorized company knowledge and portfolio documents rather than from memory.
- id: portfolio-monitor
name: Portfolio Monitor
title: Portfolio Tracking
role_description: Track portfolio company news, updates, and signals worth a partner's attention.
avatar_seed: portfolio-monitor
type: built-in
system_prompt: >-
You help a venture fund keep track of its portfolio. From authorized portfolio documents and
updates, summarize what changed for a company, flag anything that looks like a risk or a
milestone, and say plainly when you have no recent information rather than guessing. Cite the
document behind every statement. Do not speculate about valuations or outcomes that are not in
the source.

# Answers questions from the fund's own record: thesis memos, past deals, market notes, process
# docs. The house historian.
- id: knowledge
name: Fund Knowledge
title: Thesis & Memory
role_description: Answer questions from the fund's thesis, memos, and prior deals, with sources.
avatar_seed: knowledge
type: built-in
system_prompt: >-
You answer questions from a venture fund's authorized knowledge: thesis memos, investment
memos, prior deals, and internal notes. Cite every source. If the answer is not in authorized
knowledge, say so instead of guessing, and never disclose deal terms or LP information to
someone whose channel does not already carry them.

# Drafts LP-facing material from the fund's own numbers and updates: quarterly notes, answers to LP
# questions, capital-call context. It drafts; a partner sends.
- id: lp-relations
name: LP Relations
title: LP Reporting & Updates
role_description: Draft LP updates and answer LP questions from authorized fund data.
avatar_seed: lp-relations
type: built-in
system_prompt: >-
You draft investor-relations material for a venture fund's limited partners from authorized
fund data: quarterly updates, answers to LP questions, and portfolio summaries. Write in a
measured, factual voice. Use only figures present in authorized sources and cite them; never
estimate returns, mark-ups, or valuations that are not stated. Everything you produce is a
draft for a partner to review and send, not a message to an LP.
3 changes: 3 additions & 0 deletions examples/vc/brand.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
tenant:
id: venture
product_name: OpenBot for Venture
33 changes: 33 additions & 0 deletions examples/vc/channels.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Who can talk to which coworker. Every id in permitted_agents must name an agent in agents.yaml, and
# allowed_groups decides which people the channel is open to. The groups here — partners, investment,
# platform — are an example; map them to your own directory groups.
channels:
- id: deal-flow
name: Deal Flow
description: Screen inbound deals and brief them against the thesis.
permitted_agents: [deal-scout, knowledge]
allowed_groups: [partners, investment]

- id: diligence
name: Diligence
description: Run first-pass market and company diligence on a governed computer.
permitted_agents: [diligence-analyst, knowledge]
allowed_groups: [partners, investment]

- id: portfolio
name: Portfolio
description: Track portfolio company news, updates, and signals.
permitted_agents: [portfolio-monitor, knowledge]
allowed_groups: [partners, investment, platform]

- id: lp-relations
name: LP Relations
description: Draft LP updates and answers from authorized fund data.
permitted_agents: [lp-relations, knowledge]
allowed_groups: [partners]

- id: fund-knowledge
name: Fund Knowledge
description: Ask the fund's thesis, memos, and prior deals.
permitted_agents: [knowledge]
allowed_groups: [partners, investment, platform]
8 changes: 8 additions & 0 deletions examples/vc/knowledge.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Where authorized knowledge is read from. Only google-drive and microsoft-onedrive are supported
# today. roots are the top-level folders a source is allowed to reach; keep them scoped to what the
# coworkers above actually need. Access is still governed per channel and group, not granted here.
sources:
- type: google-drive
roots: [Deals, Portfolio, Thesis]
- type: microsoft-onedrive
roots: [LP, Fund Operations]
4 changes: 4 additions & 0 deletions examples/vc/model.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
model:
provider: openai
credential_secret_ref: openai-api-key
default_model: gpt-4.1
38 changes: 38 additions & 0 deletions tests/vc-package.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { expect, test } from "bun:test";
import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";

const vcDirectory = join(import.meta.dir, "..", "examples", "vc");

test("includes the complete venture deployment package example", () => {
for (const fileName of [
"brand.yaml",
"agents.yaml",
"channels.yaml",
"model.yaml",
"knowledge.yaml",
]) {
expect(existsSync(join(vcDirectory, fileName))).toBe(true);
}

expect(readFileSync(join(vcDirectory, "brand.yaml"), "utf8")).toContain(
"id: venture",
);
});

test("names every environment variable with a fallback, so a clone can read it", () => {
// Same property the fintech package holds: a package a checkout can load with no .env. A name here
// without a `:-` fallback would leave a clone unable to read the package.
const agents = readFileSync(join(vcDirectory, "agents.yaml"), "utf8");
const referenced = [
...agents.matchAll(/\$\{([A-Za-z_][A-Za-z0-9_]*)([^}]*)\}/g),
];

expect(referenced.length).toBeGreaterThan(0);
for (const [, name, rest] of referenced) {
expect(
rest.startsWith(":-"),
`\${${name}} in agents.yaml has no fallback, so a clone with no .env cannot read it`,
).toBe(true);
}
});