[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-83981":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":8,"htmlUrl":8,"language":9,"languages":8,"totalLinesOfCode":8,"stars":10,"forks":11,"watchers":11,"openIssues":12,"contributorsCount":12,"subscribersCount":12,"size":12,"stars1d":11,"stars7d":13,"stars30d":13,"stars90d":12,"forks30d":12,"starsTrendScore":14,"compositeScore":15,"rankGlobal":8,"rankLanguage":8,"license":16,"archived":17,"fork":17,"defaultBranch":18,"hasWiki":19,"hasPages":17,"topics":20,"createdAt":8,"pushedAt":8,"updatedAt":21,"readmeContent":22,"aiSummary":8,"trendingCount":12,"starSnapshotCount":12,"syncStatus":11,"lastSyncTime":23,"discoverSource":24},83981,"nagent","macton\u002Fnagent","macton",null,"Python",84,2,0,14,18,1.43,"MIT License",false,"main",true,[],"2026-06-12 02:04:36","# nagent\n\n**nagent** means **not-an-agent**.\n\nThe word \"agent\" suggests continuity, intent, and memory that a typical LLM loop\ndoes not actually provide. nagent is a small reference implementation. It shows\nwhat terminal \"agent-like\" workflows are when you describe the mechanics instead\nof the metaphor.\n\nThe claim is simple:\n\n**The agent is not the thing. The data is the thing.**\n\nnagent is a small reference example of a data-oriented approach to AI workflows.\n\nThe second claim follows from the first:\n\n**Don't edit the output artifacts. Edit the prompt.**\n\nIf a generator produces output you do not like, fix the generator or the inputs\nto that generator. Do not merely patch the generated output and leave the bad\ninput in place. In nagent, the conversation prompt is one of those inputs. If it\nmatters, it needs to be saveable, maintainable, organizable, and editable.\n\nThe LLM is temporary. The process is temporary. Sub-conversations are temporary.\nContext windows are temporary. What survives is explicit data: conversations,\nper-file conversations, root context files, repository history summaries,\nhistorical coupling tables, artifact neighborhoods, file summaries, split\nindexes, patch files, and other artifacts you can open in an editor.\n\nA text file, an LLM, structured tags, and a loop are how this repo implements\nthat idea. They are not the idea.\n\n```text\nrepository history\n        +\nroot context\n        +\nconversation\n        +\nartifact-local memory\n        +\nartifact summary\n        +\nhistorical coupling\n        +\nuser request\n            ->\n     LLM transformation\n            ->\n     updated artifacts\n```\n\nThis README is a teaching document for programmers who want to understand the\nreference example, the approach, and build their own version.\n\n## What It Looks Like\n\nOne `nagent` prompt can run for many turns. Reads. Shell. Sub-conversations.\nMore reasoning. Everything gets appended to the conversation file. From the\nterminal you typed one command. Under the hood the loop keeps going until the\nmodel emits a final response.\n\n```bash\nnagent \"Investigate why this Linux service fails to start. Read the unit file and related config, run diagnostic commands, explain the root cause, and propose a fix before changing anything.\"\n```\n\n```bash\nnagent \"Review this repository: identify the main entry points, run the test suite, fix the smallest failing test you find, and summarize what changed and why.\"\n```\n\n```bash\nnagent \"Plan the migration of this config format. Inspect the loader, tests, and examples, explain the risks, then make the smallest implementation change if the plan is sound.\"\n```\n\nThese are coordination tasks, not one-shot answers. nagent may read many files,\nrun commands, spawn sub-conversations for scoped work, and iterate. It does not\nbypass permissions; it runs with the same access your user and filesystem allow.\n\n---\n\n## 1. Durable Work, Disposable Workers\n\n**Idea** — Preserve work. Not processes.\n\n```text\ntemporary worker\n        |\n        v\ndurable artifacts\n        |\n        v\nnext temporary worker\n```\n\nThe data is more important than the code touching it. Behavior is a\ntransformation over explicit state. If state matters, put it in a file you can\ninspect, diff, copy, and edit. Do not hide it in process memory and call that\n\"memory.\"\n\n\n| Hidden state                      | Explicit artifact                                 |\n| --------------------------------- | ------------------------------------------------- |\n| Prompt state in a running process | Conversation files under the nagent root          |\n| Private tool traces               | Request tags and result wrappers appended as text |\n| In-memory scratch state           | Temp files, split segments, indexes, and patches  |\n| Framework-managed memory          | User-editable files                               |\n\n\n**Implementation** — `bin\u002Fnagent` stores conversations under\n`~\u002F.nagent\u002Fconversations\u002F`. It appends user prompts, model responses, tool\nresults, parser corrections, interrupts, and sub-conversation results to the\nconversation file. File-edit sessions get their own per-file conversations.\nLarge-file work creates split directories, `index.json`, segment files, summaries,\nand patch artifacts.\n\n**Example**\n\n```text\nartifact\n    +\nartifact-local memory\n    +\nhistorical artifacts\n    +\nuser request\n        ->\nLLM transformation\n        ->\nupdated artifacts\n```\n\nThe Python process is a worker. The files are the system.\n\n**Build your own:** decide which artifacts are source of truth before you design\n\"conversation behavior.\" Workers come and go. Data stays.\n\n---\n\n## 2. Text In, Text Out\n\n**Idea** — The smallest useful primitive is: file in, text out.\n\nLLMs forget. Therefore put the prompt in a file and treat the model as a\ntemporary function over that data.\n\n**Implementation** — `bin\u002Fnagent-llm-text` reads a text file, resolves provider\nand model settings, calls `generate_text_with_usage()` from\n`bin\u002Fhelpers\u002Fnagent_llm.py`, and prints plain text or JSON with token usage.\nProvider support covers `openai`, `anthropic`, `google`, and `cursor`. Defaults\ncome from `NAGENT_CONFIG` or `~\u002F.nagent\u002Fconfig.json`. CLI flags win.\n\n`bin\u002Fnagent-llm-upload` is the sibling for artifacts that need upload APIs:\nimages, PDFs, office files, code documents. It rejects `.zip`, enforces a 50 MB\nlimit, returns text or JSON.\n\n**Example**\n\n```bash\necho \"What is 2+2?\" > question.txt\nnagent-llm-text --file question.txt\n```\n\nEverything else in nagent is orchestration around this. Do not skip it.\n\n**Build your own:** implement `generate_text(file) -> str` first. Boring.\nSeparate. Provider churn should not rewrite your loop.\n\n---\n\n## 3. Conversations Are Editable State\n\n**Idea** — The conversation file is not chat history. It is working state.\n\nTool transcript. Correction channel. Continuation point. Mutable artifact. Memory\ngoes stale. Therefore let people save, load, summarize, edit, branch, trim,\ncopy, diff, version, and rewrite conversations.\n\n**The conversation does not own its memory. The user does.**\n\n\n| Session memory               | Artifact memory              |\n| ---------------------------- | ---------------------------- |\n| Belongs to a running session | Belongs to a file on disk    |\n| Often opaque                 | Openable and diffable        |\n| Dies with the process        | Survives worker replacement  |\n| Optimized for chat UX        | Optimized for preserved work |\n\n\n**Implementation** — `bin\u002Fnagent` names conversations with\n`default_conversation_name()` from hostname and shell identity via\n`default_pid()`. It migrates legacy root-level conversation files into\n`conversations\u002F`. Maintenance commands: `--save-conversation`,\n`--load-conversation`, `--summarize`, `--edit-conversation`.\n\nThere are two forms of editing. Explicit editing goes through commands:\n`--save-conversation`, `--load-conversation`, `--summarize`,\n`--edit-conversation`. Implicit editing comes from the fact that conversations\nare ordinary files: open them, trim them, rewrite them, diff them, copy them,\nversion them, script them. Delete stale tool spam, fix a bad assumption, replace\nten pages with one paragraph. `--edit-conversation` automates one path: archive\ncurrent file, run file-edit on the archive, load the result.\n\nRoot context is explicit too. `load_root_context()` reads `~\u002F.nagent\u002Fcontext.yaml`\nor `~\u002F.nagent\u002Fcontext.md`. YAML can be a list or `{ \"paths\": [...] }`. Nested\n`context.yaml` files expand recursively.\n\n**Example**\n\n```bash\nnagent --status\nnagent --save-conversation before-refactor\nnagent --load-conversation before-refactor\nnagent --summarize\nnagent --edit-conversation \"keep the decisions and remove obsolete logs\"\n```\n\n**Build your own:** memory is a data structure on disk. Editing history is\nmaintenance, not corruption.\n\n---\n\n## 4. Teach The Model An Output Format\n\n**Idea** — Free-form model output is hard to execute. Use a visible protocol.\n\nThe startup prompt lists the only tags the model may emit. The parser is strict:\nrecognized tags and whitespace. Nothing else.\n\n**Implementation** — `build_initial_context()` and `create_initial_text()` in\n`bin\u002Fnagent` assemble runtime context: instance facts, environment, git remotes,\ndiscovered tool descriptions, context-management rules, write rules, large-file\nguidance, the structured tag protocol, optional file-edit history, root context,\nrole instructions. The tag list and usage rules live inside `\u003Cinitial_context>`,\nso refreshed context carries the current protocol with it.\n`parse_response()` parses with regex. `process_tags()` dispatches handlers.\n\nTags:\n\n\n| Tag                                           | Meaning                                |\n| --------------------------------------------- | -------------------------------------- |\n| `\u003Cnagent-response>...\u003C\u002Fnagent-response>`      | Human response or child result.        |\n| `\u003Cnagent-read path=\"...\"\u002F>`                   | Read a small file inline.              |\n| `\u003Cnagent-file-read path=\"...\"\u002F>`              | Read a file; split first if needed.    |\n| `\u003Cnagent-file-patch index=\"...\"\u002F>`            | Merge edited split segments via index. |\n| `\u003Cnagent-write path=\"...\">...\u003C\u002Fnagent-write>` | Write to an allowed path.              |\n| `\u003Cnagent-shell>...\u003C\u002Fnagent-shell>`            | Run shell; append output.              |\n| `\u003Cnagent-next>...\u003C\u002Fnagent-next>`              | Append a continuation prompt.          |\n| `\u003Cnagent-conversation>...\u003C\u002Fnagent-conversation>` | Start an isolated sub-conversation. |\n\n\nHandlers append `\u003Cnagent-read-result>`, `\u003Cnagent-file-read-result>`,\n`\u003Cnagent-file-patch-result>`, `\u003Cnagent-write-result>`, `\u003Cnagent-shell-result>`,\n`\u003Cnagent-conversation-result>`. These are not secret return values. They are\nconversation data.\n\n**Example**\n\n```xml\n\u003Cnagent-read path=\"README.md\" \u002F>\n\u003Cnagent-shell>python3 -m unittest discover -s tests -v\u003C\u002Fnagent-shell>\n\u003Cnagent-response>Done.\u003C\u002Fnagent-response>\n```\n\n**Build your own:** put the contract in the prompt. Enforce it in a small parser.\nIf you cannot read the protocol, you cannot debug the system.\n\n---\n\n## 5. The Loop\n\n**Idea** — \"Agent behavior\" is mostly: append, call, parse, act, append, repeat.\n\nThat pattern is the core loop. Heavier systems add infrastructure around the\nsame steps.\n\n**Implementation** — Read this path:\n\n```text\nmain()\n  run_agent_loop()\n    call_llm()\n    parse_response()\n    process_tags()\n```\n\n`run_agent_loop()` appends the user prompt, sends the whole conversation to\n`nagent-llm-text --json`, appends valid output, processes tags, appends results,\nloops when an action or `\u003Cnagent-next>` added state.\n\nParser retries are visible. Bad output goes into `\u003Cagent-response>` plus a\n`\u003Csystem>` correction. Up to `MAX_FORMAT_RETRIES` (3). Provider errors append\ntoo. Failures become data, not invisible control flow.\n\n`TokenStats` tracks turns, conversation input size, recursive input\u002Foutput tokens.\nNo provider usage? Estimate from character count. Child `--json` output rolls up\ninto recursive totals.\n\n**Example**\n\n```text\nappend user prompt to conversation file\nloop:\n    response = send conversation file to LLM\n    append response to conversation file\n    if response contains action tags:\n        run those actions\n        append results to conversation file\n        continue loop\n    if response contains \u003Cnagent-response>:\n        print it and stop\n```\n\n**Build your own:** after every action, append to durable state and call the\nmodel again. Do not stash retry logic in RAM and pretend that is fine.\n\n---\n\n## 6. Persistent Per-File Memory\n\n**Idea** — One conversation grows too large. Attach memory to artifacts.\n\nWork keeps coming back to the same files. Therefore give each file its own\npersistent local memory.\n\n```text\nmain conversation\n        |\n        +-- file A memory\n        |\n        +-- file B memory\n        |\n        +-- file C memory\n```\n\n**Implementation** — `bin\u002Fnagent-file-edit` resolves a file-specific\nconversation, delegates to `bin\u002Fnagent --file-edit`. Index:\n`~\u002F.nagent\u002Fconversations\u002Ffile-index-{pid}.json`. Stable file ids from device +\ninode via `file_id_for_path()`, not just paths. Rename with same inode? Still\nworks. Legacy path-only indexes normalize to `by_file_id`.\n\nPer-file conversations hold prior investigations, dead ends, local assumptions,\nedit history, git history blocks, summaries, split\u002Fpatch state. Main conversation\nstays smaller. Noise lives next to the artifact.\n\n**Example**\n\n```bash\nnagent-file-edit --file src\u002Ffoo.py \"add error handling\"\nnagent-file-edit --file src\u002Ffoo.py --clear\nnagent --list-file-edits\n```\n\n```json\n{\n  \"by_file_id\": {\n    \"2050:123456\": {\n      \"file_id\": \"2050:123456\",\n      \"path\": \"\u002Frepo\u002Fsrc\u002Ffoo.py\",\n      \"conversation\": \"foo-0c2f...\"\n    }\n  }\n}\n```\n\n**Build your own:** when work orbits one artifact, store memory on that identity.\nSession memory = what happened today. Artifact memory = what we learned about\nthis file.\n\n---\n\n## 7. Repository History As Data\n\n**Idea** — A repo is not only the current tree. History is data too.\n\nTransform git history into editing context for a target file. Not vague\n\"retrieval.\" Explicit transformation of historical artifacts into working input.\n\n```text\ngit history\n    ->\ncommit\u002Ffile summaries\n    ->\nfile-edit initial context\n    ->\nbetter edit decisions\n```\n\n**Implementation** — On file-edit start (with provider\u002Fmodel),\n`file_edit_history_and_summary_block()` gathers git history.\n`git_file_history()` reads recent commits. `summarize_new_file_commits()` asks\nthe LLM for one-line summaries of new commits; reuses cached summaries from prior\ninitial context. `format_file_history()` records editors, step history, co-edited\nfiles, summarized commits.\n\n`run_file_summary()` calls `nagent-file-summarize`; result goes in\n`{file-summary}`. Injected with `{file-history}`. Hints, not commands.\n\n**Example**\n\n```text\n{file-history}\nFile: src\u002Ffoo.py\n\nIndividuals who edited this file:\n- Alice \u003Calice@example.com>: 3 commits\n\nStep-by-step history:\n- 2026-05-01 abc123 Alice: Adds validation.\n\nSummarized commits:\n- \u003Cfull-hash> (abc123): Adds validation to foo parsing.\n{\u002Ffile-history}\n\n{file-summary}\nFile: \u002Frepo\u002Fsrc\u002Ffoo.py\nSource: nagent-file-summarize\n\nImplements foo parsing and validation.\n{\u002Ffile-summary}\n```\n\n**Build your own:** turn history into explicit context blocks. Cache summaries in\nthe durable conversation. Do not re-pay LLM cost for unchanged history.\n\n---\n\n## 8. Historical Coupling And Artifact Neighborhoods\n\n**Idea** — A file lives in a neighborhood of related artifacts.\n\nFiles that change together in git history are hints: tests, headers, config,\npaired implementation. High co-edit rate means \"look here maybe.\" Not \"edit\neverything.\"\n\n```text\ntarget file\n        |\n        +-- historical summary\n        +-- co-edited files\n        +-- local conversation\n        +-- split indexes\n```\n\n**Implementation** — `coedited_file_rows()` counts files in the same commits as\nthe target, labels high\u002Fmedium\u002Flow co-edit rate. `format_file_history()` puts the\ntable in file-edit context and adds guidance: inspect high co-edit files when\nthe change may touch interfaces, tests, config, or paired code. High co-edit\nfiles are candidates for inspection, not automatic edit targets. Do not edit\nthem unless the request or evidence requires it.\n\n**Example**\n\n\n| file              | commits together | historical co-edit rate |\n| ----------------- | ---------------- | ----------------------- |\n| `src\u002Ffoo_test.py` | 7                | high (70%)              |\n| `src\u002Ffoo.h`       | 5                | medium (50%)            |\n\n\nThe table says \"changed with this file.\" It does not say \"must change now.\"\n\n**Build your own:** compute neighborhoods from history. Present as inspection\nguidance. Ground edits in the current request and current code, not historical\nassociation alone.\n\n---\n\n## 9. Disposable Sub-Conversations\n\n**Idea** — Exploration creates noise. Spawn disposable workers.\n\nSub-conversations are temporary nagent processes with isolated conversations.\nTheir lifetime does not matter. The artifact they return matters.\n\n\n| Long-lived agent abstractions  | Disposable workers               |\n| ------------------------------ | -------------------------------- |\n| Identity is central            | Output artifact is central       |\n| Shared context gets noisy      | Child context is isolated        |\n| Parent absorbs all exploration | Parent gets a concise result     |\n| Delegation implies personality | Delegation is context management |\n\n\n**Implementation** — `\u003Cnagent-conversation>` is the protocol tag for delegated\nsub-conversations. The parent starts `bin\u002Fnagent` with same root, provider, model,\nconfig, pid; `--invocation delegated`; parent conversation recorded; UUID child\nconversation; `--json`.\nParent appends `\u003Cnagent-conversation-result>` with child name, exit code, output,\nstderr, token totals.\n\nThe child has its own conversation file. No shared context except explicit prompt\nand result text.\n\n**Example**\n\n```xml\n\u003Cnagent-conversation>\nInspect the split and patch tests. Return only the behaviors the README should explain.\n\u003C\u002Fnagent-conversation>\n```\n\n**Build your own:** child loops for bounded investigation and noisy diagnostics.\nReturn a distilled artifact to the parent, not every intermediate step.\n\n---\n\n## 10. Controlled Writes\n\n**Idea** — A loop that writes files needs explicit boundaries.\n\nnagent is a reference implementation with conventions, not a sandbox. Shell runs\nwith your permissions. Structured writes are checked. That is not a security\nboundary. Do not pretend it is.\n\n**Implementation** — `file_edit_rules()` writes policy into initial context.\n`validate_write_path()` and `execute_write()` enforce `\u003Cnagent-write>`.\n\n\n| Mode              | Structured write boundary                                            |\n| ----------------- | -------------------------------------------------------------------- |\n| Main conversation | `\u002Ftmp`, `\u002Fvar\u002Ftmp`, or `$TMPDIR` only.                               |\n| Per-file edit     | Target file (by path or file id), or split segments for that source. |\n\n\nLarge-file rule: edit split segments for the target, merge with\n`nagent-file-patch`. Rejected writes append\n`\u003Cnagent-write-result status=\"error\">` to the conversation.\n\n**Example**\n\n```xml\n\u003Cnagent-write path=\"\u002Ftmp\u002Fnagent-note.txt\">scratch note\u003C\u002Fnagent-write>\n```\n\nSame tag on `src\u002Ffoo.py` in main mode? Rejected. Visible error. Use\n`nagent-file-edit --file src\u002Ffoo.py` for project edits.\n\n**Build your own:** write boundaries in prompt and handler. Say where the line\nis. Mean it.\n\n---\n\n## 11. Large Files As Explicit Artifacts\n\n**Idea** — Big files exceed context. Split them. Do not pretend they fit.\n\n```text\nlarge source file\n    ->\nsplit index + segment files\n    ->\nbounded edits\n    ->\npatch artifact\n    ->\nupdated source file\n```\n\n**Implementation** — Inline reads cap at 64 KB in `bin\u002Fnagent`. `\u003Cnagent-file-read>`\ncalls `nagent-file-split` when larger. Split uses\n`bin\u002Fhelpers\u002Fnagent_file_split_lib.py` and type helpers for `txt`, `md`, `cpp`,\n`py`, `xml`, `js`, `ts`, `json`, `yaml`, `go`, `rs`, `java`. Writes segment\nfiles and `index.json`: source path, hash, size, line count, split type, target\nbytes, natural flag, timestamps, segment count, line ranges.\n\nNatural splitters prefer structure: headings, blank lines, Python defs, brace\ndepth, JSON\u002FYAML depth, XML tags, declarations. `--refresh` rebuilds from index\nafter source changes.\n\n`nagent-file-patch` validates source hash (unless `--force`), merges segments,\nwrites unified diff patch, applies merged source, refreshes index.\n`--dry-run` \u002F `--no-apply` for partial workflows.\n\n`nagent-file-summarize`: small files inline; over 64 KB via\n`nagent-file-split --summarize`; per-segment summaries in `index.json`; combined\nsummary returned.\n\n**Example**\n\n```bash\nnagent-file-split --file src\u002Fbig.py --output \u002Ftmp\u002Fbig-split --json\n# edit \u002Ftmp\u002Fbig-split\u002Fbig-0001.py\nnagent-file-patch --index \u002Ftmp\u002Fbig-split\u002Findex.json --json\nnagent-file-summarize --file src\u002Fbig.py --json\n```\n\n**Build your own:** chunking is a data structure. Index it. Hash the source.\nEdit bounded segments. Emit a patch artifact.\n\n---\n\n## 12. Tool Discovery\n\n**Idea** — Tool capability should be explicit data too.\n\nNo central registry. Tools describe themselves.\n\n**Implementation** — `exit_on_description()` in `bin\u002Fhelpers\u002Fnagent_cli.py` prints\npath + description when `--description` is in `sys.argv`.\n`collect_bin_tool_descriptions()` runs each executable in `bin\u002F` with\n`--description` and inserts results into initial context.\n\n\n| Tool                    | Role                                           |\n| ----------------------- | ---------------------------------------------- |\n| `nagent`                | Main structured conversation loop.             |\n| `nagent-llm-text`       | Send a text file to the configured LLM.        |\n| `nagent-llm-upload`     | Upload a supported file with a prompt.         |\n| `nagent-file-edit`      | Per-file conversation for one source file.     |\n| `nagent-file-split`     | Split large file into segments + `index.json`. |\n| `nagent-file-patch`     | Merge segments, write patch, validate hashes.  |\n| `nagent-file-summarize` | Summarize inline or via split summaries.       |\n\n\n**Example**\n\n```bash\nnagent --description\nnagent-file-split --description\n```\n\nStartup prompt = executable descriptions + root context + environment + mode\nrules. Even discovery is a data pipeline.\n\n**Build your own:** tools emit capability text. Assemble prompts from that. Do\nnot maintain a hidden registry that drifts.\n\n---\n\n## 13. How This Differs From Frameworks\n\n**Idea** — Own the data inputs. Keep them visible and editable.\n\nnagent uses plain files, Python, subprocesses, structured text. The interesting\npart is artifact management and explicit data flow, not tool calling by itself.\nThe point is not to argue against frameworks. The point is to keep the inputs to\nthe system out of an opaque layer that hides, rewrites, stores, or modifies the\ndata you are using. LLM providers already transform data enough. nagent keeps as\nmuch control as it can by making prompts, conversations, tool results, summaries,\nindexes, and patches transparent and editable.\n\n**Implementation** — Read `bin\u002Fnagent`, `bin\u002Fhelpers\u002F`, thin wrappers in\n`bin\u002F`, tests in `tests\u002F`. That is the system.\n\n\n| Framework-style system       | nagent                  |\n| ---------------------------- | ----------------------- |\n| hidden or managed state      | explicit files          |\n| session memory               | artifact memory         |\n| object\u002Fservice graph         | data artifacts          |\n| central tool registry        | executable descriptions |\n| long-lived agent abstraction | disposable workers      |\n| opaque orchestration         | visible transformations |\n\n\n\n| Common term | nagent framing                      |\n| ----------- | ----------------------------------- |\n| memory      | editable artifact                   |\n| retrieval   | preserved work \u002F historical context |\n| agent       | temporary transformation function   |\n| context     | explicit input data                 |\n\n\n\n| Object graphs                                     | Data artifacts                         |\n| ------------------------------------------------- | -------------------------------------- |\n| Behavior distributed across services and objects. | Behavior is transformation over files. |\n| State behind interfaces.                          | State in an editor buffer.             |\n| Runtime topology is central.                      | Artifact shape is central.             |\n\n\n\n| Retrieval                    | Preserved work                                                     |\n| ---------------------------- | ------------------------------------------------------------------ |\n| Find chunks at query time.   | Keep conversations, summaries, history, indexes as durable inputs. |\n| Context as a service result. | Context as editable data.                                          |\n\n\n**Example**\n\n```text\nconversation file\n    -> LLM output with tags\n    -> parser\n    -> action handlers\n    -> result wrappers appended to conversation file\n```\n\n**Build your own:** use a framework when it buys something concrete. If the\ngoal is to learn the data flow, start with files and transformations.\n\n---\n\n## 14. Build Your Own\n\n**Idea** — Copy it, steal pieces, or reject it. Your call.\n\nThe minimal system is not mystical. Small loop over explicit state.\n\n**Implementation** — Read in order:\n\n```text\nmain()\n  run_agent_loop()\n    call_llm()\n    parse_response()\n    process_tags()\n```\n\nThen:\n\n```text\nbin\u002Fhelpers\u002Fnagent_llm.py\nbin\u002Fhelpers\u002Fnagent_cli.py\nbin\u002Fhelpers\u002Fnagent_file_edit_lib.py\nbin\u002Fhelpers\u002Fnagent_file_split_lib.py\nbin\u002Fhelpers\u002Fnagent_file_patch_lib.py\nbin\u002Fhelpers\u002Fnagent_file_summarize_lib.py\n```\n\nTests are executable notes: parser, conversation lifecycle, root context,\nretries, tokens, sub-conversations, result wrappers, write validation, file ids,\nfile-edit index, git history, co-edited files, summaries, split\u002Fpatch, uploads,\nproviders, tool descriptions, JSON output.\n\n**Example**\n\n1. `generate_text(file) -> str`\n2. Growing conversation document\n3. Initial context with the contract\n4. Output format + parser\n5. Handlers that append results to state\n6. Loop after actions\n7. Visible retry on malformed output\n8. Child loops for delegation\n9. Per-artifact memory\n10. Repository history → context blocks\n11. Split\u002Findex\u002Fpatch for large files\n12. Save\u002Fload\u002Fedit\u002Fsummarize for memory maintenance\n\n**Build your own:** preserve work before preserving workers. If you can inspect,\nedit, copy, summarize, and replay the artifacts, the loop can stay small.\n\n---\n\n## Setup\n\n```bash\npip install -r requirements.txt\nexport PATH=\"$PWD\u002Fbin:$PATH\"\nmkdir -p ~\u002F.nagent\ncp config.example.json ~\u002F.nagent\u002Fconfig.json\n```\n\nConfig: `NAGENT_CONFIG` or `~\u002F.nagent\u002Fconfig.json`. CLI overrides config.\n\n```json\n{\n  \"provider\": \"openai\",\n  \"model\": \"gpt-5.5\"\n}\n```\n\n\n| Provider    | Default model       | Credential environment variable      |\n| ----------- | ------------------- | ------------------------------------ |\n| `openai`    | `gpt-5.5`           | `OPENAI_API_KEY`                     |\n| `anthropic` | `claude-sonnet-4-6` | `ANTHROPIC_API_KEY`                  |\n| `google`    | `gemini-2.5-flash`  | `GOOGLE_API_KEY` or `GEMINI_API_KEY` |\n| `cursor`    | `composer-2.5`      | `CURSOR_API_KEY`                     |\n\n\n## Common Commands\n\n```bash\nnagent \"your prompt here\"\necho \"prompt from stdin\" | nagent\nnagent \"Use this instruction, then read stdin:\" -\nnagent --status --json\nnagent --list-models --json\nnagent --clear\nnagent --save-conversation saved-copy\nnagent --load-conversation saved-copy\nnagent --summarize\nnagent --edit-conversation \"summarize useful parts and remove noise\"\nnagent --file-edit src\u002Ffoo.py \"make this change\"\nnagent --list-file-edits\n\nnagent-llm-text --file question.txt --json\nnagent-llm-upload --file diagram.png --prompt \"Explain the diagram.\" --json\nnagent-file-edit --file src\u002Ffoo.py \"add validation\"\nnagent-file-split --file src\u002Fbig.py --output \u002Ftmp\u002Fbig-split --json\nnagent-file-patch --index \u002Ftmp\u002Fbig-split\u002Findex.json --json\nnagent-file-summarize --file src\u002Fbig.py --json\n```\n\n`--help` for flags. `--description` for what a tool contributes to startup\ncontext.\n\n## Tests\n\n```bash\npython3 -m unittest discover -s tests -v\n```\n\nSome tests mock providers. Live integration tests need real credentials.\n\n## License\n\nMIT — see [LICENSE](LICENSE).","2026-06-11 04:11:57","CREATED_QUERY"]