@formio/uag-openai

中文文档
2.0.0发布于 2026/11/13MITCommonJS构建来源已验证近 30 天下载 3234

OpenAI engine for the Form.io Universal Agent Gateway (UAG): structured extraction, with research over read-only tools, on OpenAI or any server with its chat completions API (Ollama, vLLM, LM Studio, OpenRouter); and decisions with probabilities on OpenAI

原始使用文档
文档目录6 节
  1. Settings
  2. Instances
  3. Decisions
  4. Choosing a model
  5. How it works
  6. Using it in your own server

@formio/uag-openai

Form.io UAG › Engines › this page

The OpenAI engine for the UAG Agent API. An instance is one of two kinds:

  • agent (the default): extracts and generates open values on OpenAI's Responses API, or, through Chat Completions, on any server that implements that API: local models (Ollama, vLLM, LM Studio) and routers (OpenRouter). When a task lists read-only tools in uagTools, it researches with them first. Grok and Gemini have their own packages built on it: grok and gemini.
  • decision: decides closed-set fields with a probability for each answer, on OpenAI's Decisions API, like the jev engine. See Decisions.

It is included in the formio/uag Docker image. With the UAG installed from npm, install it next to it:

npm install @formio/uag-openai

Enable it by naming it, and set its model and key:

UAG_ENGINES=openai
OPENAI_API_KEY=...
OPENAI_MODEL=<a dated model ID>

Its tasks are Agentic Formflow, so on a self-hosted project the UAG also needs a LICENSE_KEY that includes the UAG for the project's endpoint (see Licensing); a project on Form.io's hosted service needs none. A form's chat needs no license on Form.io Open Source or a hosted project.

Settings

SettingVariablesDefault
kindUAG_ENGINE_<NAME>_KIND, OPENAI_KINDagent; decision for the Decisions API
modelUAG_ENGINE_<NAME>_MODEL, OPENAI_MODELrequired; there is no default
apiKeyUAG_ENGINE_<NAME>_API_KEY; OPENAI_API_KEY for OpenAI itself onlyrequired for OpenAI itself (secret)
baseURLUAG_ENGINE_<NAME>_BASE_URL, OPENAI_BASE_URLhttps://api.openai.com/v1
structuredOutputUAG_ENGINE_<NAME>_STRUCTURED_OUTPUT, OPENAI_STRUCTURED_OUTPUTjson_schema
reasoningEffortUAG_ENGINE_<NAME>_REASONING_EFFORT, OPENAI_REASONING_EFFORTnot sent
apiUAG_ENGINE_<NAME>_API, OPENAI_APIresponses for OpenAI itself; chat for any other server
maxOptionsUAG_ENGINE_<NAME>_MAX_OPTIONS255, the Decisions API's limit and the most it takes; decision kind only

<NAME> is the instance name, upper-cased with - as _. An instance's own variable wins over the shared one.

OpenAI's own variables, OPENAI_API_KEY, OPENAI_ORG_ID, OPENAI_PROJECT_ID and OPENAI_CUSTOM_HEADERS, are sent only to OpenAI itself (api.openai.com). An instance whose baseURL is any other server, including a proxy in front of OpenAI, gets none of them: give it its own key with UAG_ENGINE_<NAME>_API_KEY, or none for a server that needs no key. Grok, Gemini and the other engines built on this one never get them either.

structuredOutput says how the server is asked for the answer:

ModeUse when
json_schemaThe server supports strict JSON schema response formats: OpenAI, and recent vLLM, Ollama and OpenRouter models.
json_objectThe server supports JSON mode but not schemas. The schema goes in the prompt.
promptThe server supports neither. The schema goes in the prompt, and the answer is read from the text.

In every mode, an answer that is not a JSON object fails as an engine failure, and the UAG routes the fields to the next engine.

Instances

A local model through Ollama, next to Claude, with no key:

UAG_ENGINES=jev,local:openai,claude
UAG_ENGINE_LOCAL_BASE_URL=http://ollama:11434/v1
UAG_ENGINE_LOCAL_MODEL=llama4:16x17b
CLAUDE_API_KEY=...

For Grok and Gemini, use their own engines (grok, gemini), which have the right endpoints and keys built in. Any other OpenAI-compatible server works with baseURL; check its documentation for model IDs and for which structuredOutput mode it supports.

Decisions

With kind set to decision, an instance is a decision engine on OpenAI's Decisions API. It answers the same questions jev does, with all of a task's decision fields in one request:

UAG questionDecisions API questionAnswer
yes/no (a field addressed, affirmed or denied)predicatethe probability it holds
choice (radio, select, checkbox)choicethe option, a probability for each, and a confidence
score (an ordered scale)scorethe position on the scale, a probability for each level, and a confidence
UAG_ENGINES=decide:openai,writer:openai
OPENAI_API_KEY=...
UAG_ENGINE_DECIDE_KIND=decision
UAG_ENGINE_DECIDE_MODEL=gpt-6-luna
UAG_ENGINE_WRITER_MODEL=<a dated model ID>

Its answers are reported calibrated: true, like jev's, and the same thresholds (uagThreshold, uagUncertainBand) apply. OpenAI makes no calibration guarantee for these probabilities, and neither does any provider: measure with uag-eval --engine decide on your own labeled examples before relying on the default thresholds, and again when you change the model.

  • A question the API declines is left undecided, so its field is reported missing or decided by the next engine in the routing list.
  • A request with more than 400 questions is split across calls.
  • maxOptions caps the options one choice question may have. Closed sets with more options go to an agent engine.
  • Both jev and an openai decision instance can be enabled; list both in routing.decision to fall back from one to the other.

Choosing a model

There is no default model: set model to a specific, dated model ID, not an alias that moves. Answers differ between models, so compare them on your own labeled examples before switching (uag-eval measures decision engines only).

How it works

  • Which API. With OpenAI itself, the engine uses the Responses API, which lets current models reason while they use tools (Chat Completions refuses tools on a reasoning model). Nothing is stored at OpenAI (store: false): the model's reasoning carries across research turns as encrypted reasoning items, sent back with the history. With any other server (baseURL), it uses Chat Completions, which local servers and routers implement. Set api to responses or chat to choose yourself, for example for a gateway in front of OpenAI.
  • Dates with OpenAI. OpenAI's strict mode corrupts dates when the schema constrains them (the year comes back as 1000, 1010, 3362 …), so with OpenAI itself the engine writes each field's format (such as date) and pattern into its description instead. Measured October 2026; other servers keep the constraints, and the UAG validates every value either way.
  • Extraction makes one request, constrained as structuredOutput says. Values from this engine are always reported as suggested, and only the requested fields are returned.
  • Research: when a task lists read-only tools, the model may call them first through function calling, up to agentApi.research.maxIterations turns. Every call goes back through the UAG with the caller's identity, and tool errors are returned to the model. The model then answers with tools turned off. It never writes: the UAG validates the values and saves them itself. Tasks that research need a server that supports function calling; on one that does not, the request fails as an engine failure.
  • Failures: a refusal, a content filter, a truncated answer or an answer that is not JSON fails as an engine failure, and the UAG falls back to the next engine.
  • Aborts: the routing timeout (for research, agentApi.research.timeout) aborts the request, and research stops before its next call.

Using it in your own server

Name it in configuration instead of UAG_ENGINES, with options that take precedence over the environment:

const server = new UAGServer({
    engines: [{ name: 'local', type: 'openai', options: { baseURL: 'http://localhost:11434/v1', model: 'llama4:16x17b' } }],
});

License: MIT.

版本与发布记录

@formio/uag-openai 共发布 13 个版本,首次发布于 2026/10/30;过去 12 个月发布了 13 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
2.0.0latest2026/11/132 天前
2.0.0-rc.11rc2026/11/105 天前
2.0.0-rc.102026/11/087 天前
2.0.0-rc.92026/11/079 天前
2.0.0-rc.82026/11/069 天前
2.0.0-rc.72026/11/0610 天前

关于 @formio/uag-openai 的常见问题

@formio/uag-openai 是什么?

OpenAI engine for the Form.io Universal Agent Gateway (UAG): structured extraction, with research over read-only tools, on OpenAI or any server with its chat completions API (Ollama, vLLM, LM Studio, OpenRouter); and decisions with probabilities on OpenAI

如何安装 @formio/uag-openai?

在项目目录运行 npm install @formio/uag-openai,或使用 pnpm add / yarn add / bun add。

@formio/uag-openai 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/formio__uag-openai 是否存在。

@formio/uag-openai 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@formio/uag-openai 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@formio/uag-openai 可以商用吗?

@formio/uag-openai 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@formio/uag-openai 的下载量有多少?

根据 npm 官方下载统计,@formio/uag-openai 在 2026/10/16 – 2026/11/14 这 30 天内被下载 3,234 次,日均约 108 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@formio/uag-openai 还在维护吗?

最新版本 2.0.0 发布于 2026/11/13(2 天前);至今共发布 13 个版本,其中过去 12 个月发布了 13 个;首次发布于 2026/10/30。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。