跳转到内容

从代码中运行

面向开发者。从开发者手册选择 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。你也可以在代码中直接写出这些值。

这个程序仍然需要一个平台。在用户使用之前,先运行一次设置程序。请看平台。

导出 是什么
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.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。


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。

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 在启动服务前检查表结构和已完成的数据版本。它在服务器的整个生命周期内持有共享锁。备份和恢复步骤见 部署。

Terminal window
pnpm --filter @openbot-build/openbot migrate

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 日志器,就能把它们发送到其他服务。每条日志包含什么,以及完整示例,请看错误日志。