The Runtime Loop: How LobeHub Turns a Request into Work
In LobeHub, the important event is not the model’s first token but the transition from a user request into a bounded operation. This chapter follows that transition through Model Runtime, Agent Runtime, context construction, tools, human intervention, persistence, and termination. The result is a practical way to judge what an Agent has actually done, where it stopped, and which layer is responsible when the outcome is wrong.
A model adapter alone cannot provide that explanation. It can send a request to a provider and receive a response, but it does not know whether the response should trigger a file edit, wait for approval, be retried, or become part of a recurring task. LobeHub places those decisions in a loop above the adapter. That division is what turns a chat response into work with state.
Two runtimes, one operation
The first distinction is between Model Runtime and Agent Runtime. Model Runtime is the translation layer between LobeHub and different AI providers. Its common interface can expose streaming chat, structured-object generation, embeddings, image or video creation, speech synthesis, and transcription where a provider supports them. Provider-specific request formats and authentication remain behind the adapter boundary, while LobeHub receives a common shape for the operation it is trying to perform.
That normalization is valuable, but it is deliberately limited. It does not make providers identical. A model may lack vision, function calling, structured output, or a particular media capability. Providers also differ in latency, errors, streaming behavior, and how faithfully they follow tool schemas. The common interface hides transport variation so the rest of LobeHub can operate; it cannot erase the conditions under which a provider succeeds.
Model Runtime does carry useful lifecycle responsibilities. It can run a check before a model call, capture usage, invoke a completion hook for cost or tracing, and report errors. In the implementation, those hooks are designed so a failure in billing or tracing does not turn a completed answer into a failed response. This is an important boundary: observability and accounting are attached to model activity, but they do not decide the Agent’s next action.
Agent Runtime owns that next-action problem. The Agent supplies a runner—a decision function often represented by GeneralChatAgent—and the runtime executes the typed instruction that the runner returns. The instruction may be a model call, a tool call, a batch of tool calls, a context-compression step, a human-approval request, an interruption settlement, or a finish. The runtime state carries messages, status, step count, usage, cost, pending interactions, tool information, and operation metadata. In other words, the model proposes a move; the runtime decides how that move becomes a state transition.
Context engineering sits between those layers. Before a model call, LobeHub does not simply forward the raw transcript. Its context engine filters abandoned placeholders, truncates history when configured, assembles system instructions, adds Agent identity and workspace facts, injects knowledge or Memory, transforms Group and Task messages, processes attachments and tool calls, and applies final cleanup. The order matters. A group message may need to be relabeled before tool calls are normalized; a compressed summary must be available before the next model request; a tool that has been activated for one step must be represented consistently in both the schema and the prompt.
The operation is also durable. On the server path, the LLM executor checks that a referenced parent message still exists, creates or reuses an assistant message, and uses an operation- and step-scoped idempotency key. It streams events while accumulating content and tool calls, then finalizes the turn. An operation record can retain its model and provider, trigger, status, step and limit data, token and cost aggregates, intervention counts, timing, and a pointer to a fuller trace. This record does not make the result correct, but it makes a later question—what happened during this run?—answerable.
Streaming and persistence have different jobs. A stream tells the interface that a response is growing, a tool has started, or approval is needed. Durable message and operation state tells the next runtime step what actually exists. That distinction prevents a transient browser event from becoming the only record of an action. It also explains why LobeHub is careful about message identity: a retry should continue the same assistant turn, while two independent model instructions in one step should not overwrite one another. A visible spinner is presentation; the assistant message, tool rows, status, and operation metadata are the state on which recovery depends.
Imagine that a user asks an Agent to prepare a competitor briefing and save it for later. The first model call may decide to search the web and read a project document. The search and document tools can produce separate results, but the next model call needs both results attached to the same requesting assistant turn. If the user then asks the Agent to publish the briefing, that is a new authority decision, not an automatic consequence of having gathered the information. The runtime’s parent IDs, tool-call IDs, and status transitions keep those stages distinguishable. They also give a reviewer a way to tell whether the Agent found evidence, drafted text, or actually performed the external action.
This separation creates hidden coupling that an operator must still respect. The Agent runner, executor, context builder, message store, stream transport, and provider adapter must agree on identifiers and phase names. If one layer loses a parent or emits a tool name the next layer cannot resolve, the operation can fail even though the model itself produced sensible text. LobeHub’s architecture reduces that coupling through typed instructions and shared event shapes; it does not eliminate the need to maintain the contracts across client, server, database, and provider paths.
How the plan–execute loop stays bounded
The normal path begins when LobeHub receives user input. The Agent runner asks for an LLM call, and the runtime passes a model-specific payload through context engineering. The model may return ordinary text, tool calls, or both. If there are no tool calls, the Agent can finish. If there are calls, the runner must decide what kind of authority each call requires before anything is executed.
The first filter is scope. LobeHub can provide an explicit set of allowed tool names for an operation or a Group node. An omitted allow-list preserves the ordinary behavior; an explicit empty list blocks all tools. Calls whose names are not in the allowed set become blocked results rather than silently expanding the Agent’s authority. This is a small but consequential distinction: the model’s ability to name a function is not itself proof that the current operation is allowed to invoke it.
The next filter is intervention policy. LobeHub evaluates global audits before per-tool configuration. The default security rules cover patterns associated with destructive filesystem commands, system configuration, disk formatting, privilege changes, and access to credential-bearing files. A matching global rule can require intervention even when a user has chosen an automatic mode. Per-tool or dynamic rules can add their own conditions, while a manual or allow-list mode determines whether calls not explicitly cleared must wait. Headless mode does not mean “ignore security”; intervention-required calls are converted into blocked tool results so the model receives a failure it can reason about.
This creates three useful outcomes. A direct response needs no tool authority. A safe call can proceed immediately. A sensitive or uncertain call becomes a visible request for a human decision. LobeHub’s checker also treats unknown tools cautiously in interactive modes: if a tool is not represented in the manifest, it requires intervention rather than assuming the model’s name is valid. These controls are not a complete security system—the rules are pattern-based, and a tool’s own behavior and host environment remain outside the checker—but they make authority a deliberate state in the loop.
The distinction is especially important for batches. Several calls that do not require intervention can be executed concurrently from the same base state, then merged into the operation in tool-call order. A mixed response can execute the safe calls first and park the sensitive siblings for approval. This avoids making the user approve harmless, independent lookups merely because one other call in the same model response is consequential. It also means the runtime must preserve correlation: each result needs the right tool-call ID and the assistant message that requested it.
When approval is required, LobeHub does not merely display a button over an already completed action. The runtime changes to a waiting state and stores the pending calls. The approval executor records the assistant owner, creates durable pending tool messages, publishes a structured event for the client, and retains the mapping between tool-call IDs and message IDs. On resume, the runtime can execute the approved batch and continue with the results. If the user aborts instead, pending calls are settled as aborted rather than left in a permanent pending state. This is why approval belongs to the execution model: the operation genuinely stops, and the next transition depends on a human input.
A malformed tool name illustrates another bounded path. If the model emits a tool call but no available manifest can resolve it, simply finishing would produce an apparently successful conversation in which the requested action never occurred. LobeHub instead returns a rejected tool result with feedback telling the model to use a declared name, preserves provider-specific signatures where needed, and limits the number of feedback rounds. After that limit, the operation fails rather than consuming steps indefinitely. The choice favors a visible failure over a silent false completion.
Long operations have two different kinds of budget. The first is context capacity. Before a new model call, the Agent estimates the message and tool-definition load against the model window. If the threshold is exceeded, it emits a compression instruction. A summary is inserted into the context and the Agent continues from the compressed messages; later growth can trigger compression again. Compression is therefore a transition in the operation, not a magical increase in model memory; information that was summarized may lose detail, and the summary itself becomes part of what the next model sees.
The second budget is execution effort. The runtime increments a step count and can calculate cost and usage after model or tool activity. When a configured cost limit is exceeded, it can stop, interrupt for later resumption, or emit a warning according to policy. When the maximum step count is crossed, the runtime marks a force-finish path: existing tools may settle, but the next model call is stripped of tools and receives guidance to produce a final response. This prevents a model that keeps asking for actions from turning a bounded request into an unbounded loop.
Provider failure is handled as another explicit transition. The server LLM executor runs classified retry attempts, publishes retry events, and checks the durable operation state before waiting or trying again. If the operation was interrupted during a retry window, it stops retrying and persists whatever usable partial output exists. It also performs a parent-message preflight: if a conversation parent was deleted while the operation was in flight, the executor reports that specific failure instead of attaching a new response to an invalid chain. These details are easy to miss in a chat interface, but they determine whether a long run can be trusted after cancellation, reload, or concurrent edits.
The loop’s final state is not merely “the model returned text.” It is a durable relationship among an assistant turn, its tool children, any human decisions, the operation record, and the next context. That relationship is what allows LobeHub to render progress, resume an approval, account for cost, and explain an error without reconstructing events from a single final bubble.
The practical conclusion is restrained. LobeHub’s Agent is autonomous only inside a state machine that delegates decisions to a model and enforces scope, intervention, budget, persistence, and termination around them. Once this loop is visible, the next question is no longer whether the Agent has tools in the abstract. It is which Skills, Tools, knowledge, and personal context should be admitted into each call, and how that capability surface can grow without overwhelming the operation.