从代码中运行
面向开发者。从开发者手册选择 API 接入、App 发布或项目贡献。
openbot
程序能满足大多数需要。如果你需要更多,可以在自己的程序中启动 OpenBot。这样你就能加入自己的模型、工具、路由和 App
Index 来源。
OpenBot 用 Effect 构建。你用 Layer 来组装它。Layer 是 Effect 中用来构建服务的“配方”。创建 Layer 不会打开网络或数据库。这些操作在你启动它时才会发生。
这个程序和 openbot 做的事情相同:
import { Launch, Server } from "@openbot-build/openbot"
Launch.main(Server.layerLive)Launch.main 先读取命令行。带 --help
时它显示帮助后停止,这时不需要任何设置。然后它从环境变量或机密文件中读取配置中的变量。它会阻止到私有地址的出站连接,并在启动失败时写入日志。然后它运行你给它的 Layer,直到进程停止。它把 Node.js 服务和 fetch
HTTP 客户端交给这个 Layer。Launch.server
是同一个程序的 Effect 形式,供你自己运行。请把 NodeServices.layer 交给它。
EnvironmentConfiguration.load
给出同样的设置:host、port、databaseUrl、secretKeys、clusterSecret、clusterHost
和 outboundAllow。你也可以在代码中直接写出这些值。
这个程序仍然需要一个平台。在用户使用之前,先运行一次设置程序。请看平台。
包导出了什么
Section titled “包导出了什么”| 导出 | 是什么 |
|---|---|
Server.layerLive(options) |
带有自己的 Node.js HTTP 服务器和真实外部服务的 OpenBot。openbot-server 运行它。 |
Server.layer(options) |
同样的服务器,但不带它需要的服务。请看OpenBot 需要的服务。 |
Server.layerFixed(options) |
和 Server.layer 一样,但它先把一份登录配置写入平台设置。用于测试和开发。 |
Server.layerApp(options) |
OpenBot 的路由和服务,用于你已有的 HTTP 服务器。 |
Server.layerApi |
只有 HTTP 路由。 |
Launch.main(make)、Launch.server(make) |
像 openbot-server 一样运行 make 给出的 Layer。 |
OpenBot.layerShared(options) |
与实例同生命周期的服务:数据库连接池、密钥和共享设置。 |
OpenBot.layer(options) |
路由背后的服务:登录、令牌、权限、存储、Chat 和 App。 |
OpenBot.layerOutside |
来自 OpenBot 外部的真实服务,例如 App 的网络。 |
OpenBot.layerLive(options) |
带有真实外部服务、没有宿主工具的 OpenBot.layer。 |
HostTools |
你的程序交给每个 Chat 的工具。请看添加工具。 |
DatabasePostgres |
数据库 Layer 和 migrate 程序。 |
EnvironmentConfiguration |
从环境变量读取实例设置。 |
Auth、Chats、AppHost、AppTools、Configuration |
用于高级配置的服务类型。 |
子路径 @openbot-build/openbot/Development 导出开发服务器。见
运行开发服务器。
Server.layerLive 接受实例选项和应用选项。Server.layer 和 Server.layerFixed
接受同样的选项,但不接受 secretKeys,因为你的程序会把共享服务交给它们。
| 选项 | 类型 | 是什么 |
|---|---|---|
host |
string |
必需。监听的地址,例如 127.0.0.1。 |
port |
number |
必需。监听的端口,例如 3000。 |
databaseUrl |
Redacted<string> |
必需。PostgreSQL URL。 |
secretKeys |
Redacted<string> |
密钥列表。请看密钥。 |
clusterSecret |
Redacted<string> |
必填。至少 32 个字符。所有节点使用相同机密认证私有 RPC。 |
clusterHost |
string |
可选。其他节点能访问的地址。默认使用绑定的 HTTP 地址。 |
服务器不接受登录选项。它从平台设置中读取公开源、平台提供方和登录密钥。
- 在完成设置之前,除
/health外的每个路由都返回503和SetupRequired。 - OpenBot 每次使用这些设置时才读取它们。当其中某个设置改变时,下一个请求就会使用新值。服务器只构建一次,所以正在运行的请求和 Turn 会继续。
Server.layerFixed 接受一份 auth 配置。它启动时,会把 auth
的公开源、登录密钥和提供方写入平台设置。之后它和 Server.layer
一样工作,所以之后对平台设置的修改也会立即生效。测试和开发服务器使用它。每个服务器都会把应用的服务交给你的程序,所以测试可以使用它们。
| 选项 | 作用 |
|---|---|
builtinModels |
在代码中给出、每个组织都能使用的模型。请看模型。 |
builtinModels.defaultModel |
当新 Chat 的 Bot 没有指定模型时,这个 Chat 使用的模型。它是 builtinModels 中的一个。只有模拟的平台设置它。 |
routes |
一个带有你自己 HTTP 路由的 Layer。 |
indexSources |
App Index 搜索的更多来源,与 OpenBot Index 并列。 |
indexWork |
App Index 后台任务的时间设置:{ intervalMs, retryMs }。 |
有些值以前是选项。现在它们是数据库中的设置,所以每个实例都共享它们:
| 旧选项 | 设置 |
|---|---|
appRestrictions |
平台设置中的 appRestrictions。 |
appReadRules |
组织设置中的 appReadRules。 |
bots.helperModel |
组织设置中的 rulesModel 和 botMemoryModel。 |
bots.requestTimeout |
组织设置中的 requestTimeoutMs。 |
bots.memory |
组织设置中的 botMemory。 |
appEncryptionKey |
实例选项 secretKeys。 |
OpenBot 需要的服务
Section titled “OpenBot 需要的服务”OpenBot.layer、Server.layer 和 Server.layerFixed
不会构建来自 OpenBot 外部的服务。它们需要这些服务,由你的程序以 Layer 的形式交给它们。这样测试可以交给它们假的服务,你的程序也可以交给它们自己的服务。
| 服务 | 是什么 | 真实服务器使用的 Layer |
|---|---|---|
| 共享服务 | 数据库连接池、密钥和共享设置。 | OpenBot.layerShared(options) |
外部服务(OpenBot.Outside) |
Computer 提供方的驱动、Live 后端、密码管理器的读取器、App 的网络和检查、域名的 DNS 检查、App Index 的公共网络,以及 App 的发现。 | OpenBot.layerOutside |
宿主工具(HostTools) |
你的程序交给每个 Chat 的工具。 | HostTools.none |
| 平台服务 | 文件、路径、随机数和 HTTP 客户端。 | NodeServices.layer 和 FetchHttpClient.layer |
Server.layerLive 提供除平台服务以外的全部服务。Launch.main
提供平台服务。下面的程序和 Launch.main(Server.layerLive)
做的事情相同,只是每个部分都写了出来:
import { HostTools, Launch, OpenBot, Server } from "@openbot-build/openbot"import { Layer } from "effect"
Launch.main((settings) => Server.layer(settings).pipe( Layer.provide(Layer.merge(OpenBot.layerOutside, HostTools.none)), Layer.provideMerge(OpenBot.layerShared(settings)), ),)选项
chats、discovery、computerDrivers、liveBackends、vaultReaders、appProbe、appNetwork、domainControl
和 indexPublicNetwork 已经不再存在。请改为交给对应的服务。
模型来自数据库中的模型提供方和 builtinModels。请看模型。
Bot 记忆遵循组织设置中的
botMemory。
服务器持有应用级服务和活动执行。每个 Turn 在自己的作用域中创建模型和工具。保存的执行身份包含成员、原始 token、Bot 和委派限制。请求不再维持成员运行时。每个 Chat 同时只允许一个 Turn 推进。命令、检查点、事件和结果保存在 PostgreSQL 中,可跨节点和重启继续使用。关闭 HTTP 事件流只关闭观察;取消使用独立命令。
工具是模型可以调用的函数。用 Effect AI 创建它,然后用 HostTools.layer
把 toolkit 及其处理器交给 OpenBot。每个 Chat 的每个 Turn 都可以调用这个工具。handlers
接收 Chat 的 ID,并给出它的 Turn 使用的处理器。每个 Turn 在开始时构建它们,在结束时关闭它们。
import { type Configuration, HostTools, Launch, OpenBot, Server,} from "@openbot-build/openbot"import { DateTime, Effect, Layer, Schema } from "effect"import { Tool, Toolkit } from "effect/ai"
const CurrentTime = Tool.make("CurrentTime", { description: "Returns the current time on the server.", parameters: Schema.Struct({}), success: Schema.String,})const toolkit = Toolkit.make(CurrentTime)const handlers = toolkit.toLayer({ CurrentTime: () => Effect.map(DateTime.now, DateTime.formatIso),})
const server = (settings: Configuration.Settings) => Server.layer(settings).pipe( Layer.provide( Layer.merge( OpenBot.layerOutside, HostTools.layer({ toolkit, handlers: () => handlers }), ), ), Layer.provideMerge(OpenBot.layerShared(settings)), )
Launch.main(server)如果每次调用都需要一个决定,就在 Tool.make 中加上
needsApproval: true。这样 OpenBot 会为它检查能力
tools.call。当这次调用需要决策者时,Bot 会得到一个待定的结果,调用会在之后被允许时运行。请看
Request。
你自己的路由
Section titled “你自己的路由”routes 向同一个服务器添加 HTTP 路由。它是一个 Layer。这个 Layer 可以用 Auth
服务检查登录 cookie。
import { HttpRouter, HttpServerResponse } from "effect/http"
const routes = HttpRouter.add( "GET", "/status", HttpServerResponse.text("ready"),)
Server.layerLive({ ...settings, routes })不要使用 /auth/ 或 /v1/ 下的路径。它们属于 OpenBot。
使用你自己的 HTTP 服务器
Section titled “使用你自己的 HTTP 服务器”Server.layerApp(options) 提供 OpenBot 的路由和服务。它需要和 Server.layer
相同的服务。Server.layerApi
只提供 OpenBot 的路由。它还会为失败的请求添加错误日志。
Server.layerLive、Server.layer 和 Server.layerFixed
会启动它们自己的 Node.js 服务器。要把 OpenBot 放进你已有的服务器,请自己组装同样的部件。Server.layer
如何只构建一次应用,并在设置之前用 SetupRequired 回答,请读
packages/openbot/src/app/Server.ts。把登录密钥放在平台设置中,不要放在你自己的环境变量里。每个实例都必须使用同一个登录密钥。
DatabasePostgres.migrate
准备表结构和初始数据门禁。它只能将空数据库标记为就绪。完整升级使用维护命令,需要
OPENBOT_DATABASE_URL 和
OPENBOT_SECRET_KEYS。运行前停止所有实例。OpenBot.layerShared
在启动服务前检查表结构和已完成的数据版本。它在服务器的整个生命周期内持有共享锁。备份和恢复步骤见
部署。
pnpm --filter @openbot-build/openbot migrate运行开发服务器
Section titled “运行开发服务器”pnpm dev
运行开发服务器。它有一个本地测试账户、模拟的模型和一个模拟的 App。基于 OpenBot 构建的项目可以在自己的程序中运行同样的服务器:
import { NodeRuntime } from "@effect/platform-node"import * as Development from "@openbot-build/openbot/Development"
NodeRuntime.runMain(Development.launch)Development.launch 读取与 Launch.main 相同的设置,以及
OPENBOT_DEV_PUBLIC_ORIGIN。设置了 OPENBOT_DEV_S3_*
变量时,它会把这个本地对象存储用于文件,并创建存储桶。Development.layer
是没有这些步骤的服务器。它需要平台服务,例如 NodeServices.layer 和
FetchHttpClient.layer,Development.launch
会提供它们。它自己写入平台设置,所以它不需要设置程序。Development.developmentSecret
用第一个机密密钥生成登录密钥,所以重启后它保持不变。永远不要在生产环境中使用开发服务器。任何能访问它的人都可以登录。
把错误日志发送到你自己的服务
Section titled “把错误日志发送到你自己的服务”OpenBot 把失败写成错误日志。添加你自己的 Effect 日志器,就能把它们发送到其他服务。每条日志包含什么,以及完整示例,请看错误日志。