Download the PHP package milpa/agent without Composer

On this page you can find all versions of the php package milpa/agent. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package agent

Milpa

Milpa Agent
Long-running coding sessions for the Milpa PHP framework.

Packagist PHP

# Milpa Agent An agent that answers one question needs nothing. An agent that works for an hour needs the session to be **a thing that exists** — something you can pause, resume, audit and stop. That is all this package is: a session is an **event-sourced stream** whose events are the conversation, whose human gates are the permissions, and whose state carries the plan. It brings no LLM client (`milpa/ai-gateway` has one), no tools (`milpa/tool-runtime` has those), and no storage (`milpa/event-store` has that). It brings the vocabulary that turns those into a working day. ## Install ## The shape ## Why event-sourced Because what matters about a long session is both **where it ended up** and **how it got there**. A row with `current_state` answers the first and erases the second on every `UPDATE` — and the second is exactly what someone wants the next day: which permission was granted and when, what the agent asked, what it was told, at which step it went wrong. With a stream, *"the agent ran forty steps on its own"* is a verifiable claim instead of a hope. It also makes the rest possible. Resuming is replaying. Compacting is appending a summary **without losing the turns it summarises** — `window()` shortens what the model sees while the stream keeps everything, so the evidence behind a decision survives the context that produced it. A pending question is an event without its pair, not a flag someone has to remember to clear. Nothing is ever rewritten. Revoking a permission does not delete the grant; it appends on top of it. A log you can edit stops being useful for the one thing a log is for. ## What a session carries | | | |---|---| | `goal` / `mode` | why it was opened, and how much autonomy it runs with | | `turns` | the conversation, including tool calls — resuming without them means repeating work already done | | `plan` / `todos` | the plan lives in the stream, not in the prompt: one that only exists inside the context is lost at the first compaction, which is exactly when it matters most. `stateBriefing()` renders it back into the window, so the agent rereads what it wrote — a plan you can only audit is half a feature | | `permissions` | consented **per operation and per session** — *"yes to `make`, in this session"* is a sentence someone can evaluate; *"yes to whatever the agent decides"* is not | | `question` | while one is open the session is not runnable. An agent that "asks" and proceeds on its assumption did not ask, it narrated | | `decisions` | what a human resolved when the session stopped to ask — with **who** resolved it, and whether that identity was verified | | `runFirst` / `obligationDeclared` | a standing obligation (`--first`) outlives the turn that typed it. Passing an empty one **lifts it** — the same authority that set it, unsetting it — and the lift ends the *discipline*, not just this turn's list: declared or lifted, the last one wins | | `summary` / `compactedThrough` | what the model is spared, never what the log forgets | ## The policy `SessionPolicy` is the piece that decides how far an automatic process may go over someone's code, so it is written to be argued with by reading it: it calls nobody, appends nothing, and takes three facts about an operation. **The order of the rules is the rule.** The signature is evaluated *before* the granted permission and before the mode. Evaluated later, a `grant` on that operation — or an `auto` mode — would let it through, and there goes the only gate that names the concrete call instead of the category. Reading is never asked. An agent you must authorise for every query is not a supervised agent, it is a useless one — and the attention you spend on what does not matter is the attention you stop spending on what does. ## Deadlines: a question does not wait forever A question can carry an `expiresAt`, and passing it **ends the session** with a reason: **Expiry is declared, not derived.** It could be computed by comparing the deadline with the clock, and that is exactly why it is appended: a derived expiry leaves no trace of *when* it was noticed, and a session that died of silence is precisely the case where somebody will want to know. The clock did not close the session — `expireIfDue()` did, at a concrete instant, and left a fact. The event is called `session.answer_window_closed` and not "question expired" on purpose. **The question did not expire**: it is still the same question and still valid. What ran out is the authority to answer it *within this session*. It ends the whole session rather than just the question, because the question exists so the agent can continue and without an answer it cannot: closing it and leaving the session alive would send the agent to ask the same thing again or — worse — to proceed without the permission it was waiting for. `expiresAt: null` still means "waits indefinitely", and that remains a valid choice. **There is no default window**: how long a human has to answer depends on who operates the agent, and a number invented in this package would kill sessions belonging to people who never chose it. ## Who answered `answer()` takes an optional `Principal`, and the principal carries whether its identity was **verified**: The two sources are not worth the same, and merging them would be worse than storing nothing. An authenticated context has a credential behind it; a terminal reports the OS user, **which anyone holding that terminal can be**. Recording the second as if it were the first would manufacture a chain of custody that does not exist — *"rod authorised it"* when what is known is *"whoever had rod's machine authorised it"*. Replay never raises trust: anything that does not explicitly say `verified: true` reads as unverified. And `null` — nobody said who — stays `null`; sessions recorded before this existed are not given an invented principal. ## Why a question was asked — as a code Since 0.4 a `PendingQuestion` carries `reason`: a stable code (`permission`, `signature`, `target_not_named`) next to the human-readable text. The text gets rewritten and translated; the code does not — a projection counting how many pauses each authority produced must never parse prose. And when a question is answered, the resulting decision **inherits** `reason` and `why` from the question that produced it, so a confirmation can be consumed as data: "this operation, over this target, was confirmed by the human" is readable from the fact alone. That is what closes the loop — a *yes* to "did you mean HelloPlugin?" names the target, the retry passes, and a yes to one target names no other. ## Compaction When a session outgrows its window, `Compactor` appends a summary of the old turns and keeps the recent ones intact. **The window shrinks; the history does not.** Two details that are the whole design: The threshold counts turns **not yet summarised**, not all of them. Counting the total would make a long session compact on every turn — the total never goes down — appending one summary per turn, each hiding the last. Recent turns survive intact because a summary answers *"what has happened"* and not *"what were we doing a minute ago"*, and the second is what the model needs to take the next step. Summarising everything leaves a session that knows its history and not its place — visible as an agent that, right after compacting, repeats work or asks something it just got answered. The default `FactualSummarizer` **does not call the model.** For a coding session what compaction loses is not nuance, it is facts: the goal, which tools ran, what was authorised, what the human decided, what is still pending. All of it is already in the stream, exact, and deriving it costs no call and cannot hallucinate. And a made-up summary is worse than expensive — it gets *appended as what happened*, and from then on the model works from a version of the session nobody wrote. Swap in your own `Summarizer` if you want prose. The replaceable prose is followed by a versioned operational-facts JSON block derived through `SessionFacts::operationalFacts()`. It retains bounded call results, documented artifact identities, explicit verification verdicts, execution receipts and their argument digests, decisions, evidence, and whether each call is still the latest recorded call for its artifact. Calls and executions stay separate: a call owns target/result data, while only an execution receipt proves materialisation, and the package does not join them without a producer-declared link. Execution-effect currentness is therefore reported as unknown rather than inferred. Supplying a custom `Summarizer` replaces only the prose; it cannot remove this structured continuity block. ## Autonomy modes `ask` pauses before anything that mutates. `acknowledge` announces and continues. `auto` runs to the end. What **no** mode can skip is a signature. An operation declaring `requiresConfirmation` demands consent that names *that* call with *those* arguments, and pre-approving "whatever the agent decides" is signing a blank cheque. `auto` means *don't ask me about the reversible* — never *don't ask me*. That line lives in the type and not in a config file, because a line you can move with an environment variable is not a line. ## License Apache-2.0 © Rodrigo Vicente - TeamX Agency --- Milpa is designed, built, and maintained by **[Rodrigo Vicente - TeamX Agency](https://teamx.agency/?utm_source=github&utm_medium=readme&utm_campaign=milpa&utm_content=agent)**. ### Effect observations and progress `SessionStore::recordEffectObservation()` records an execution observer's measured artifact and behavioral-evidence identities. Pass its sequence as `effectObservationSeq` to `recordToolCall()`. The observation is separate from tool output and the operation's `mutating` ceiling. `ProgressReceipt` checks the call/observation correlation and counts identities only once per session, including across progress windows. A proposal and its first host application have distinct identities. `EffectObservation(known: true)` with empty identity lists proves no measured growth. An unknown, missing, reused or mismatched linked observation yields `ProgressReceipt::UNKNOWN` unless another fact proves growth. Calls without a link keep the historical proxy for compatibility. These facts measure progress; they do not certify goal completion or change authorization (greenhouse0346/0663).

All versions of agent with dependencies

PHP Build Version
Package Version
Requires php Version >=8.3
milpa/event-store Version >=0.3 <1.0
milpa/command Version >=0.25.1 <1.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package milpa/agent contains the following files

Loading the files please wait ...