从代码中运行
openbot 程序能满足大多数需要。如果你需要更多,可以在自己的程序中启动 OpenBot。
这样你就能加入自己的模型、工具、路由和 App Index 来源。
OpenBot 用 Effect 构建。你用 Layer 来组装它。Layer 是 Effect 中用来构建服务的“配方”。创建 Layer 不会打开网络或数据库。这些操作在你启动它时才会发生。
最小的程序
这个程序和 openbot 做的事情相同:
import { NodeRuntime } from "@effect/platform-node"import { EnvironmentConfiguration, Server } from "@openbot-build/openbot"import { Effect, Layer } from "effect"import { FetchHttpClient } from "effect/http"
NodeRuntime.runMain( Effect.gen(function* () { const settings = yield* EnvironmentConfiguration.load return yield* Layer.launch( Server.layer(settings).pipe(Layer.provide(FetchHttpClient.layer)), ) }),)EnvironmentConfiguration.load 读取配置中的变量。它返回 host、port、databaseUrl、secretKeys 和 tls。
你也可以在代码中直接写出这些值。
这个程序仍然需要一个平台。在用户使用之前,先运行一次设置程序。请看平台。
包导出了什么
| 导出 | 是什么 |
|---|---|
Server.layer(options) |
带有自己的 Node.js HTTP 或 HTTPS 服务器的 OpenBot。它从平台设置中读取登录配置。 |
Server.layerFixed(options) |
使用一份固定登录配置的 OpenBot。用于测试和开发服务器。 |
Server.layerApi(options) |
只有 HTTP 路由,用于你已有的 HTTP 服务器。 |
OpenBot.layerShared(options) |
与实例同生命周期的服务:数据库连接池、密钥和共享设置。 |
OpenBot.layer(options) |
路由背后的服务:登录、令牌、权限、存储、Session 和 App。 |
DatabasePostgres |
数据库 Layer 和 migrate 程序。 |
EnvironmentConfiguration |
从环境变量读取实例设置。 |
Auth、Sessions、AppHost、AppPlugin、Configuration |
用于高级配置的服务类型。 |
选项
Server.layer 接受实例选项和应用选项。
实例选项
| 选项 | 类型 | 是什么 |
|---|---|---|
host |
string |
必需。监听的地址,例如 127.0.0.1。 |
port |
number |
必需。监听的端口,例如 3000。 |
databaseUrl |
Redacted<string> |
必需。PostgreSQL URL。 |
secretKeys |
Redacted<string> |
必需。密钥列表。请看密钥。 |
tls |
对象 | 可选。{ certFile, keyFile },即 PEM 文件的路径。这样 OpenBot 会自己提供 HTTPS。 |
登录
Server.layer 不接受登录选项。它从平台设置中读取公开源、平台提供方和登录密钥。
- 在完成设置之前,除
/health外的每个路由都返回503和SetupRequired。 - 当其中某个设置改变时,服务器会用新值构建一个新的应用。新应用先开始接收请求,然后旧应用停止。
Server.layerFixed 则使用一份固定的 auth 配置,从不构建新应用。它还把应用的服务交给你的程序,所以测试可以使用它们。当数据库中没有平台设置时,它会先按 auth 的 publicOrigin 写入平台设置。测试和开发服务器使用它。
应用选项
| 选项 | 作用 |
|---|---|
sessions |
Session 的工具和记忆。见下文。 |
builtinModels |
在代码中给出、每个组织都能使用的模型。请看模型。 |
routes |
一个函数,接收登录配置,返回一个带有你自己 HTTP 路由的 Layer。 |
discovery |
一个在网上查找 App 的 Layer。默认通过互联网读取公开的 Catalog。 |
indexSources |
App Index 搜索的更多来源,与 OpenBot Index 并列。 |
indexWork |
App Index 后台任务的时间设置:{ intervalMs, retryMs }。 |
有些值以前是选项。现在它们是数据库中的设置,所以每个实例都共享它们:
| 旧选项 | 设置 |
|---|---|
appRestrictions |
平台设置中的 appRestrictions。 |
appReadRules |
组织设置中的 appReadRules。 |
agents.helperModel |
组织设置中的 rulesModel 和 agentMemoryModel。 |
agents.requestTimeout |
组织设置中的 requestTimeoutMs。 |
agents.memory |
组织设置中的 agentMemory。 |
appEncryptionKey |
实例选项 secretKeys。 |
Session
sessions 选项决定 Session(会话)如何完成工作。
| 字段 | 作用 |
|---|---|
runtime |
Agent 的定义:toolkit、plugin、providers、compaction 等。 |
layerExecution |
一个函数,为每个 Turn 构建额外的服务,例如工具处理器。 |
memory |
学到的记忆:你自己的 model 和 policy。 |
模型来自数据库中的模型提供方和 builtinModels。请看模型。
新 Session 的记忆开关来自组织设置中的 memory。请看 Memory。
添加工具
工具是模型可以调用的函数。用 Effect AI 创建它,然后把 toolkit 及其处理器交给 OpenBot:
import { type Configuration, Server } from "@openbot-build/openbot"import { 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.sync(() => new Date().toISOString()),})
const server = (settings: Configuration.Settings) => Server.layer({ ...settings, sessions: { runtime: { toolkit }, layerExecution: () => handlers, }, }).pipe(Layer.provide(handlers))如果每次调用都需要一个决定,就在 Tool.make 中加上 needsApproval: true。这样 OpenBot 会为它创建一个 tools.call Request。请看 Request。
你自己的路由
routes 向同一个服务器添加 HTTP 路由。它是一个函数,接收当前的登录配置,返回一个 Layer。这个 Layer 可以用 Auth 服务检查登录 cookie。
import { HttpRouter, HttpServerResponse } from "effect/http"
const routes = HttpRouter.add( "GET", "/status", HttpServerResponse.text("ready"),)
Server.layer({ ...settings, routes: () => routes })不要使用 /auth/ 或 /v1/ 下的路径。它们属于 OpenBot。
使用你自己的 HTTP 服务器
Server.layerApp(options) 返回一个函数。这个函数接收一份登录配置,返回对应的 OpenBot 路由和服务。
Server.layerApi({ publicOrigin }) 只提供 OpenBot 的路由。它还会为失败的请求添加错误日志。
Server.layer 和 Server.layerFixed 会启动它们自己的 Node.js 服务器。
要把 OpenBot 放进你已有的服务器,请自己组装同样的部件。layerFixed 如何使用一份配置,请读 packages/openbot/src/app/Server.ts。平台设置改变时 Server.layer 如何构建新应用,请读 packages/openbot/src/app/Supervisor.ts。
把登录密钥放在平台设置中,不要放在你自己的环境变量里。每个实例都必须使用同一个登录密钥。
迁移数据库
DatabasePostgres.migrate 应用迁移。OpenBot.layerShared 只检查表是否存在,不存在就失败。
在启动服务器之前,用单独的程序运行迁移:
import { NodeRuntime, NodeServices } from "@effect/platform-node"import { DatabasePostgres } from "@openbot-build/openbot"import { Config, Effect, Layer } from "effect"
NodeRuntime.runMain( DatabasePostgres.migrate.pipe( Effect.provide( Layer.unwrap( Effect.map(Config.Redacted("OPENBOT_DATABASE_URL"), (databaseUrl) => DatabasePostgres.layer({ databaseUrl }), ), ).pipe(Layer.provide(NodeServices.layer)), ), ),)把错误日志发送到你自己的服务
OpenBot 把失败写成错误日志。添加你自己的 Effect 日志器,就能把它们发送到其他服务。 每条日志包含什么,以及完整示例,请看错误日志。