@alma-harness/batch

中文文档
0.41.0发布于 2026/11/04Apache-2.0TypeScriptES Module零依赖近 30 天下载 2325

Governed single-dispatch batch execution for Alma.

原始使用文档
文档目录3 节
  1. Status and cancellation (spec: governed-batch-cancellation-…
  2. Tool selection
  3. Batch call (spec: batch-call)

@alma-harness/batch

Governed single-dispatch batch execution. Node >=22 and matching Alma packages are required. createGovernedBatchRunner composes BatchSubmissionStore, BatchUsageStore, BatchAccountingStore, ExecutionResultStore, governed settlement, same-counter spend.peek, audit and SingleDispatchBatchClient capabilities.

Supply immutable configRevision (including provider account selection), bounded request/output/aggregate sizes, runTimeoutMs <=5 minutes and onBackgroundError. The host creates authorized complete manifests: scope/session, item identities, original prices/policy/controls, content/config revisions and result retention. The host derives allowed tools/media/schema; this primitive does not route policy or execute handlers. Never accept manifests/scopes/handles from model output or unverified browser input. Changing config requires a new revision; old batches must still resolve their original configuration, prices and provider account.

submit({input,rationale,loadItems,signal?}) reserves every result and awaits audit before loading content. Requests must match ordered IDs, model, batch tier and controls. Only the first durable dispatch:true response permits a provider attempt. Equal replay never loads input or submits again. The optional awaited onInputFile hook can retain upload references before create; without it no durable orphan-file inventory is claimed. Any ambiguous submission stays unresolved, even after expiry. No fallback, automatic resubmission or lease takeover exists. Explicit provider cancellation is separate from submission ownership and settlement.

collect({scope,key},{signal?}) resolves the stored handle and collects every terminal status, including failed/expired/cancelled. Every observation is journaled before governed settlement and inclusive accounting. Those are the only financial writers: neither SpendStore.add nor AuditLog.cost runs. Hashes deduplicate metadata observations only; original manifest settlement identities own charges. Unknown, unpriced and contradictory evidence stays pending for explicit reconciliation.

New output is retained only after complete, independently validated EOF. Corrupt or missing tails cannot authorize partial new output. Content bounds/failures do not stop known-usage drainage. eof describes this invocation, not a durable completion certificate. reconciliationRequired reports this collection's pending financial/content work. Existing output remains readable after a later failed GET. A crash between puts can require another GET, but never another model submission.

Copies at the provider (spec: provider-batch-retention). collect never deletes them: a job routine collects again until it has delivered. discard({scope,key}) deletes them through the client's discard, for a host that collects directly. Call it only after your own delivery. It refuses a batch with an item not yet accounted and decided.

read({scope,key}) returns persisted metadata, inclusive financial evidence and current retained item results; it makes no claim of EOF or delivery. Successful output is a backstage governed-batch-v1 envelope with ordered neutral blocks and stop. Reasoning is not a public reply; the host validates its business schema and authorizes any effects. Refusal/truncation/invalid/blocked/unavailable stay distinct. Original block decisions suppress successful outputs; missing aggregate receipts keep block-mode success pending until those decisions can be evaluated; warn preserves them. Monetary warnings are durable evidence, not calls to an external notification service.

reconcile({scope,key},query?) repairs journaled finance without provider/content access. It returns scanned/repaired/pending counts and afterId. Pages default50, maximum100; restart future passes at the beginning. Already adopted observations must still repair missing aggregate receipts, so default queries include them.

Result retention begins at submission reservation. Collection never prepares a new reservation, renews retention or resurrects erasure. Read/put respect the original binding; register result erasure/purge with the host. Successful public submit/collect promises are bounded by timeout/abort (submission also by its original deadline); cancellation does not prove dependency termination. Late acceptance/financial work is observed, and background failures report only scoped stage metadata. Permanent process loss cannot guarantee missing provider evidence.

Migrate batch accounting (which composes submission, usage and governed costs), results and audit before enabling this runner. PostgreSQL store deadlines still apply to read/reconcile. Routines and channel/business delivery require their own persistent claims; this runner never sends real messages or certifies delivery. See spec.

A failure before any dispatch grant, including an abort right after an acknowledged claim, records not_submitted when that cleanup succeeds (spec: batch-not-submitted). A lost claim acknowledgement leaves no fence, and a cleanup write can fail; the store's expiry sweep then records the state after the deadline. collect on it returns {eof:false, reconciliationRequired:false} without provider access; replaying submit returns it and never dispatches. The runner has no sweep: call the batch store's reconcileExpired from the host's scheduler.

Status and cancellation (spec: governed-batch-cancellation-adoption)

status({scope,key},{signal?}) and cancel({scope,key},{signal?}) resolve the original accepted handle under the runner's configuration. They reject missing handles, foreign scope/configuration and unsupported cancellation before HTTP. They remain available after the submission deadline, bounded by this invocation's runTimeoutMs/signal. Neither loads input nor changes durable execution or finance.

Cancellation returns {status:"requested",progress}: one validated provider acknowledgement, not terminal cancellation or a refund. A failed/ambiguous request is never retried automatically; an explicit later call is another cancellation request. Continue explicit status/collection to account for completed items and retain unknown evidence. Closing a connection does not prove dependency termination.

Tool selection

Each item's execution.controls.toolChoice must equal its loaded request.toolChoice. Supported neutral modes are auto, none, required and {type:"tool",name}; provider/model restrictions remain those documented by the providers package. Named choices are validated against the actual authorized ToolSpecs before dispatch, including with custom transport validators. Choice is part of immutable batch identity; changed choice conflicts without another input load or submission. Absence retains the old wire and replay contract.

Successful extraction items preserve their tool_use stop and ordered tool_call blocks, alongside original financial receipts. Inspect outcome, stop, expected name and validate arguments before using them. Selection invokes no business handler or personal-memory write. Read/status/collect/reconcile/cancel never infer authority to submit again from missing content, unknown usage or an absent handle.

Batch call (spec: batch-call)

createBatchCallRunner(config) sends one structured extraction by batch and retries it by reason, with no fallback or cancellation. Its configuration is the governed runner's plus the call's:

  • policy, versions, batch-tier prices, caps and consumers;
  • system, tools, toolChoice, maxTokens and resultRetentionMs;
  • an optional pure validate(output);
  • retries: { provider, invalid, not_sent, uncertain }, from 0 to 4, with no defaults;
  • retryDelayMs, and submitWindowMs of at most one hour.

Change configRevision whenever the retries, the wait or validate change.

The host's scheduler runs two loops:

const r = await calls.attempt({ scope, sessionId, key, inputRevision, intent, loadInput });
// pending: call again later. completed: publish r.output. failed: show r.reason.
if (r.status !== 'pending' && !r.settled) await calls.settle(scope, key);   // repeat until settled

Copies at the provider (spec: provider-batch-retention). When attempt or settle reports settled: true and the latest attempt is decided, the runner discards every attempt's batch at the provider. No later call reads them again. A discard that fails loses nothing and is reported to onBackgroundError with stage discard. A client without discard keeps its batches until the provider's own expiry.

What attempt does:

  • It acts only on the latest attempt. It submits a new batch, or collects, or classifies the item.
  • Attempt k+1 starts only while the reason's allowance remains, and after k × retryDelayMs. Until then it returns pending.
  • Earlier attempts count against every reason their journals support, so a count never goes down.
  • Run calls for one key one at a time, as a job lease or a transactional poll claim already does. The retry table, latest-only and settled are exact under that contract.
  • Even if calls overlap, there is never more than one batch per attempt, or more than five attempts.
  • Before an end or a submission, attempt reads the chain again, and decides again if something moved: a late acceptance, an erasure, or an earlier call's background work.

What ends the call:

  • too_long, refusal, cap and invalid_validator;
  • unavailable: a result that was erased or expired. It is never generated again;
  • an allowance used up, or five attempts.

Stopping a key: stop calling attempt, and call settle until it returns { settled: true }.

  • settle collects every batch already sent, and closes a submission that died, by the store's own clock.
  • It submits nothing and loads no input.
  • Batches in lost never returned a handle, and need the operator.

The host's loader should refuse a key it no longer wants: a refused load sends nothing.

A batch whose usage stays unknown or unpriced keeps the call pending until it is reconciled.

版本与发布记录

@alma-harness/batch 共发布 47 个版本,首次发布于 2026/09/09;过去 12 个月发布了 47 个版本。

版本发布日期距今
0.41.0latest2026/11/043 天前
0.40.02026/10/308 天前
0.39.22026/10/309 天前
0.39.12026/10/299 天前
0.39.02026/10/299 天前
0.38.02026/10/2910 天前

关于 @alma-harness/batch 的常见问题

@alma-harness/batch 是什么?

Governed single-dispatch batch execution for Alma.

如何安装 @alma-harness/batch?

在项目目录运行 npm install @alma-harness/batch,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@alma-harness/core(^0.41.0)、@alma-harness/execution(^0.41.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@alma-harness/batch 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@alma-harness/batch 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@alma-harness/batch 需要什么版本的 Node.js?

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

@alma-harness/batch 可以商用吗?

@alma-harness/batch 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@alma-harness/batch 的下载量有多少?

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

@alma-harness/batch 还在维护吗?

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