Skip to content

Memory files

The memory files service gives your account one private root folder, shared by every agent of the account, holding plain-text files in folders the agents organise themselves. Use it for anything an agent should still have next time: notes, drafts, findings, work in progress.

A path is one string relative to the root, /-separated and case-sensitive: Notes.md and notes.md are different files. A leading / is optional (/notes/a.md is notes/a.md) and a trailing / is ignored. A path has no . or .. segment, no \, no empty segment, no control character and no unpaired surrogate; each name is at most 255 characters and the whole path at most 400. A name cannot begin or end with a space, and cannot consist only of invisible characters — two names that only look identical must not be two files. Every answer returns paths in this same form, so a path can be passed back as it was shown. A folder exists only while it holds something: it comes into being with the first file under it and goes when the last one does.

It offers a trial, and it can also be enabled in full and billed per use.

Every tool works on this system's own storage only; none reaches outside it.

Its tools

Each tool is charged under an operation of its own, named in brackets at the end of its entry: one unit per call, whatever the size of the file or the answer.

Tools that only read

  • file_list lists a folder: its direct entries, or with depth (1 to 5) an indented tree that many levels below it, in path order. Give the folder as path; leave it out for the root. Folders end in /; files show their size, version token and when they were last modified. Listing the root also shows the limits in force and your account's usage against them. It only reads (file-list).
  • file_read returns a file's text with every line numbered, under a header giving its path, the lines shown, its line count, its size and its version token. Give path for one file, whole or from fromLine to toLine, or paths for up to 10 files read whole — one or the other, never both. A line that, with its line ending, is longer than the read bound (256 KiB) cannot be returned by file_read; file_search still shows it and file_edit still changes it. It only reads, and is charged once however many files it reads (file-read).
  • file_find finds the files anywhere below a folder (path, the root by default) whose path matches a pattern, with each file's size, version token and when it was last modified, sorted by path or, with sortBy: "modified", most recently modified first. It only reads (file-find).
  • file_search looks for literal text inside the files below a folder (path, the root by default), optionally only in the files matching glob, and ignores letter case unless caseSensitive is true. By mode it answers with each matching line in grep form (lines, the default, with up to 10 lines of context either side), with the files that hold a match (files), or with a count of matching lines per file (counts). It only reads (file-search).

Tools that change things and lose nothing

  • file_create makes a new file at path with its first content, which may be empty. It is refused when anything already exists at the path — edit or write the existing file instead. Any folders the path names come into being with it (file-create).
  • file_append adds text to the very end of the file at path, creating the file when nothing is there. Nothing is added between the file and the text, so start the text with a line break if it should begin a new line. It applies to whatever the file holds when the call runs, so it needs no version token, and calling it twice appends twice. When many agents append to the same file at the same moment it can still be refused VERSION_CONFLICT, having retried for you and kept losing; that refusal is rare, means nothing was written, and is always safe to answer by calling again — an append is defined against whatever the file holds right now, so repeating it is never wrong (file-append).
  • file_move moves or renames a file, or a folder with everything under it, from one path to another. It never overwrites: it is refused when anything is already at to. The root cannot be moved, nothing can be moved onto it, and a folder cannot be moved into itself. Content is untouched, so every moved file keeps its version token and its modified time (file-move).

Tools that replace or remove content, with no undo

Nothing in this service is versioned, so what these three tools replace or remove cannot be recovered.

  • file_edit replaces exact text in an existing file at path. Each of its edits (up to 20) gives an oldText, copied exactly from the file, and the newText that replaces it; an empty newText deletes the text. Each oldText must occur exactly once, unless that edit's replaceAll is true. Matching is literal and case-sensitive, spacing and line breaks included. The edits are applied in order, each to the text the ones before it left, and all or none: if any one is not found, or is found more than once, the call changes nothing and says which edit failed and how many times its text was found. One call replaces at most 100,000 occurrences in total, summed over its edits; past that it changes nothing, and a denser rewrite is a file_write. Give the version a read returned to be refused if the file has changed since (file-edit).
  • file_write creates a file, or replaces an existing file's whole content. Replacing needs the version a read of the file returned; without one the call only creates, and is refused when a file is already there (file-write).
  • file_delete deletes the file at path, or a folder and everything under it — a folder only when recursive is true; a folder named without it is refused with how many entries it holds. The root cannot be deleted. A folder the delete leaves empty goes with it (file-delete).

Read before you write

file_read gives every file a version token, such as v3, which changes whenever the file's content does. file_write over an existing file requires it, and file_edit accepts it. A call given the token is refused when the file has changed since that read, so a change another agent of your account made meanwhile is never overwritten unseen: read the file again and retry with the new token.

The line numbers file_read and file_search show, as <number><tab><text> in a read, are not part of the file. Leave them out of any text you send back: an oldText that includes them will not match.

Paging

file_list, file_find and file_search answer one page at a time. When there is more, the answer ends with a cursor: pass it back as cursor, with every other argument unchanged, for the next page. A cursor works only for your account and only with the arguments that issued it. Each tool's pageSize sets the most entries, files or matches to a page, up to 200.

pageSize belongs to the page, not to the query, so a cursor does not carry it. Send it again alongside the cursor on every page you want that size; leave it out and that page takes the tool's own default, which may be larger than the one you asked for.

A page you can ask for may still be larger than you can be handed. What any tool may return to you in one answer is bounded by your account's toolsets.max-response-chars, which is well under the largest page these tools will build: an answer past it is stored rather than returned, and you read it back with toolsets_page_response. So a pageSize near the top of its range, or a file_read near its 256 KiB bound, will usually come back stored rather than whole. Nothing is lost either way — ask for a smaller page if you want the answer inline, or raise that setting for your account.

Its setting

services.memory-file.max-depth is the most folder levels a new file path may have in your account's files, at most 20. The platform has a ceiling of its own on it, and the smaller of the two is the depth in force. It applies wherever a file is created, and to a move that lands deeper than it started — at the destination, to the deepest file moved. Lowering it hides and deletes nothing: files already deeper stay readable, editable and deletable, and stay movable anywhere that does not take them deeper still, renaming in place included.

Its limits

Four limits hold your account's files: the folder depth (maxDepth), the largest file in UTF-8 bytes (maxFileBytes), the most bytes all your files may hold together (maxTotalBytes) and the most files (maxFileCount). The folder depth is your account's setting within the platform's ceiling; the other three are the platform's. Their values are settings and can change, so they are not written here: file_list at the root shows the values in force and your account's usage against them. A call that would take a file or your account past one of them is refused and changes nothing.

Files are UTF-8 text, stored exactly as sent: no line-ending conversion, and no NUL character or unpaired surrogate.

A search is literal text. Every character in text means itself; there is no pattern language. text is 1 to 500 characters and is matched within one line, so it cannot contain a line break. A \r is an ordinary character, matching the one a Windows line ending leaves at the end of a line.

A find pattern — file_find's pattern and file_search's glob — is 1 to 200 characters in this grammar: * matches any run of characters within one name, ** as a whole segment any number of folders, ? one character, and [abc], [a-z] and [!abc] one character from (or not from) a set. Everything else is literal, a \ is not allowed, and matching is case-sensitive. A leading / is accepted and ignored, as in a path. A pattern with no / is matched against each file's name at any depth, so *.md finds every Markdown file; one with a / is matched against the file's path relative to the folder, as in notes/**/*.md.

A read is bounded. The files of one file_read may total at most 256 KiB; for a larger file, read a line range with fromLine and toLine.

A search page is bounded. Files are searched in path order, and one file_search page ends at pageSize matches, after 4 MiB of content read, 100 files opened, 2,000 files examined or, in lines mode, 262,144 characters of matching and context lines reported, whichever comes first; the match that crosses that last bound is still reported whole. A page can therefore end with a cursor and few or no matches: the rest of the folder has not been searched yet, so continue from the cursor. A file_find page likewise examines at most 2,000 files, and one that reaches that bound ends with a cursor even when it holds fewer matches than asked for.

A delete has no undo, and neither has an edit or a write: nothing is versioned, so what they replace or remove cannot be recovered.