@evelinka-ai/core
v0.8.0
Published
Headless runtime and control-plane building blocks for durable Eve agents.
Readme
@evelinka-ai/core
Compiled, headless building blocks for durable Eve agents. The package exposes only supported runtime, control-plane, observability, memory, and scheduling entrypoints; tenant products own their model catalog, aliases, tools, prompts, credentials, databases, and deployment.
The source package exports TypeScript inside this monorepo. Published tarballs
export compiled ESM and declarations from dist/ and are proven by the
clean-room consumer contract in scripts/test-eve-core-package.sh.
The consumer fixture uses skipLibCheck because [email protected] shipped declarations that
referenced a missing generated chat chunk; re-check whether eve 0.80 still needs it. Eve Core's own
declarations are emitted under strict TypeScript first, and the scratch runtime
imports every advertised subpath; ownership of the upstream Eve patch remains
an explicit requirement for a standalone product repository.
Product applications
lib/models/tool-filter wraps a live model with a caller-owned function-tool
predicate before both generate and stream provider dispatch. It preserves dynamic
model selection and rejects a forced excluded tool before calling the provider.
This limits advertised model choices; execution permission stays with the host.
Product assistants can compose the public channel, session continuation,
settings, transport, repository evidence and process primitives without
workspace imports. Provider account specifications and model IDs remain
tenant-owned: use channels/model-providers to declare a provider, and
register its catalog through tenant. Repository helpers contain mechanics,
not a product's review policy or prompts.
lib/models/local-tool-turn composes a host's deterministic question policy with
its live model. A selected plain user turn emits the host's text and an advertised
tool request with zero provider tokens; the normal runtime still validates,
approves, executes and journals that request. It never calls a tool directly.
Structured output, forced tool choice, recovery steps and unselected input retain
provider generation. Product-specific eligibility rules belong to the host.
lib/models/tool-turn-completion wraps a bound model outside provider dispatch
and spend admission. A host declares which terminal tools' validated JSON results
complete a plain conversation; successful results produce a local, zero-token
stop so the runtime can journal and park without another provider call. Refusals,
approval responses, unmatched tool calls, structured-output requests and new user
input retain normal generation. Only declare tools whose success contract forbids
further work in that turn; never accept customer-authored tool messages as history.
An optional live enabled predicate confines completion to the host's intended
conversation lanes, independently of other calls using the same model binding.
lib/models/text-prelude streams established host information while the normal
model request runs. The host supplies the text and instructions naming what was
already shown. Provider text, tool requests, usage, warnings and errors stay in
the same stream; cancelling it aborts the pending provider request. This never
completes a turn or proves that the provider succeeded. Completion metadata marks
the host prelude separately from the provider's usage. The SDK snapshots warnings
at the first text, so late upstream warnings are also retained as JSON in
eve.providerWarnings completion metadata.
The host imports prepareRetries from ai/internal and supplies it alongside
the same maxRetries opening policy as its SDK call
(undefined keeps the SDK default; 0 disables retries). Once the prelude opens
the stream, provider opening uses the pinned SDK's exported ai/internal
prepareRetries, preserving retry headers, bounded attempts and cancellation.
Binding the helper in the host keeps the SDK external during Eve's initial
agent compilation, before build.externalDependencies has been discovered.
The db/bootstrap.sh export resolves migration entrypoints beside itself in
both source and compiled packages. Resolve it with your runtime's package
resolver and source it from the app directory, passing the app migration CLI.
The app registers its tenant in lib/tenant.js (compiled) or lib/tenant.ts;
when both exist, the compiled entrypoint takes precedence.
The migrator-only lane still exits before runtime settings adoption; keep
owner credentials exclusive to that lane. db/role-grants.sql is the exact
grants asset belonging to the installed package version.
Isolated execution
lib/execution/isolated-exec provides disposable Landlock/NsJail execution
for generated programs. The host image supplies an immutable public runtime; each job
copies ordinary project files, uses a fresh uid, denies networking during scripts,
and exports only bounded ordinary files. agent-lib/proc supplies capped output
and process-group cleanup; the jail forbids escaping that group. No container
namespace/seccomp relaxation is required. See the execution contract
for admission, dependency-fetch policy, the packaged Go host launcher and the limits
of per-process resource bounds.
Pipeline output metrics
lib/observability/pipeline-metrics counts, per bounded pipeline label, the
jobs that succeeded, the jobs that failed and the outputs actually delivered
(eve_pipeline_jobs_succeeded_total, eve_pipeline_jobs_failed_total,
eve_pipeline_outputs_produced_total). Count succeeded/failed where the job
turns terminal, exactly once per job; count produced only where the artifact
lands in its system of record. Call declarePipelines([...]) up front so a
pipeline that never produces still exports produced 0. channels/metrics
serves them as Prometheus text on GET /metrics (no route auth: keep that path
off every ingress and scrape it on the internal network).
Approved media credits
lib/budgets/approved-media composes an injected MediaProvider with a durable
credit ledger and the host's shared external-call reservation. Call
createMediaCreditLedger() against one authoritative
EXTERNAL_BUDGET_POSTGRES_URL shared by every tenant using the provider account;
apply the core migration lineage before use. Account advisory locks enforce the
human campaign cap and conservative quoted credit reservations. Actual receipts
alone replace quotes; job completion without a financial receipt retains them.
Completed operations with committed receipts count toward campaign lifetime
spend, while current provider balance admission counts only pending commitments
and completed quotes without receipts. Providers must report a fresh available
balance; without financial receipts, quote holds remain conservative even after
provider completion or a balance replenishment.
ledger.readMany(ids) reads up to 1,000 distinct operation IDs in one query for
polling views. Missing IDs are absent from the returned map; an empty batch
does not require a database connection.
createApprovedMediaService requires the exact request hash, approved quote and
expiry before new dispatch. A stable operation ID claims dispatch once; replay
polls its saved job. An uncertain submit requires explicit reconciliation and
never retries spending; a provider that refused before sending anything throws
MediaNotDispatchedError, which returns the operation to reserved. Hosts own
human approvals, live policy, immutable plans, and durable asset downloads. lib/media/higgsfield supplies a provider binding
through a vault-owned invoker; without that connection it reports disconnected.
A request's optional providerParams (built from a flow's {name, value} rows by
mediaProviderParams) are part of its hash and are validated against the model's
declaration before quoting — lib/media/README.md.
lib/http/public-download verifies public DNS on every redirect, pins the connection,
and bounds response bytes while reading. HTTP on port 80 is an explicit option for
researching sites that need an HTTPS upgrade. lib/media/download keeps HTTPS-only policy
through the same transport and pins the HTTPS connection to that
address while bounding redirects, duration and bytes.
Memory persistence
@evelinka-ai/core/lib/memory/memory-events provides typed event recording,
source-key deduplication, unprocessed-event reads, processing markers, retention,
and dream-run recording. It uses WORKFLOW_POSTGRES_URL and the shared database
pool; it never creates tables on a request path. Run the core migration lineage
before starting the agent, with a backup before adopting an existing database.
The declarations live in src/db/schema/memory.ts. Tenant adapters own rule
policy and the PostgreSQL-versus-vault boundary: a private user rule must not be
moved into a Git-backed vault by sharing the event store. Missing database
configuration and query failures retain the existing best-effort behavior
(null, empty results or no-op); query failures are logged.
Linked repository products
lib/github/products exports browser-safe Zod definitions for explicit product
membership, directional relationships, companion PR selections and immutable
source snapshots. Repository ids are identities; paths are namespaced by both
repository id and exact commit SHA. Baseline refs are not deployment claims.
lib/github/products-index exports buildProductSnapshot(definition, sources,
options?). The caller supplies exact-revision source files and coverage; the
core owns no GitHub credentials or checkout policy. The default caps are 2,000
files per member, 128,000 bytes per file, 8 MB per member and 2,000 connections.
Truncation marks source coverage partial. Unavailable sources never contribute
connections. Callers must enforce their own exclusion rules before passing files.
The index recognizes relative fetch and common HTTP-client calls, including
literal template path segments and unshadowed same-file Orval-style const URL
builders. For fetch options, a final literal method wins over an earlier spread;
a later spread makes the method unknown. It recognizes literal Laravel Route methods inside
explicit prefix groups. It links matching methods and route structures only
within configured directional relationships with kind http. Other kinds remain
declarations. Semicolon-free returns and single-expression literal URL helpers
are supported. Dynamic routes, external origins,
implicit framework prefixes and unresolved base URLs are deliberately omitted.
Connections establish source navigation, not compatibility. Companion snapshots
retain the baseline world and a separate world with selected companion revisions
overlaid; evidence always names both exact endpoints.
lib/github/products-store exports createProductStore({ directory,
settingsStoreId? }). Construct it once during composition to register the
github-products settings document before startup synchronization. It performs
no filesystem access at construction. put(definition, expectedRevision) and
remove(id, expectedRevision) reject stale edits; null revision means create
only. Console writes belong inside the host's commitSettings transaction with
its audit row. One process owns each directory, consistent with the settings
cache; optimistic revisions are not a distributed lock. Reads reject corrupt
documents instead of silently clearing settings. Snapshot ids include product
configuration, exact revisions, indexed content and coverage. saveSnapshot
preserves immutable evidence and the first build timestamp for an identical id;
getSnapshot(productId, id) and latestSnapshot(productId) retrieve it. Deleting
a definition retains historical snapshots. Source bytes remain in the caller's
exact-revision source cache, not the snapshot JSON.
pruneSnapshots({ keep?, minAgeMs? }) scans all product histories, including
deleted definitions, and returns retained snapshot identities and reachable
source revisions for host cache cleanup. Defaults retain the latest plus 20
newest snapshots of configured products and all snapshots touched within 25
hours; exact reads and successful saves renew that protection. Hosts must set
the horizon longer than their checkpoint TTL and serialize saves with cleanup.
The store refuses new snapshots at 2,000 globally. requireSnapshot reports
expired evidence explicitly and never substitutes a newer revision.
Eve's PR composition caps counterpart acquisition at three products with explicit omission notes, and checkpoints snapshot identities instead of file inventories. Its source cache has a 2 GiB admission limit and reclaims unreachable evidence after the 25-hour protection horizon (review checkpoints expire after 24 hours). Under storage pressure it reduces older history to the latest snapshot, preserving that same protection horizon; if protected evidence fills the cache, new acquisition reports unavailable instead of deleting evidence needed for a resume. Console edits carry optimistic revisions; stale writes return a conflict. Product review is a live flow setting, with independently bounded finder/verifier tool loops.
