Operations

Every memory operation, reached either on the client or on a session scope that applies one session to each of them.

The examples here are fragments: they take client and session as already bound. Memco and AsyncMemco are imported from memcoai, and every other type they name — Tag, FeedbackRating, ImportedMemory and the rest — from memcoai.types.

Memory

Reached as client.memory.

class MemoryOperations(stub, call)[source]

Bases: object

The memory operations, on a synchronous client.

Reached as memory; not constructed directly.

Example

>>> with Memco() as client:
...     session = client.memory.start_session("coding")
...     result = session.search("how does X work")
Parameters:
  • stub (Any)

  • call (Callable[..., Any])

list_domains(*, timeout=None)[source]

List the memory domains available to you and describe each one: what it holds, when to search it, what belongs in it and what does not, and the tag vocabulary and format it uses.

Call when: before your first search or write of a task, and whenever you are unsure which domain a question or a finding belongs to. The slug you choose is what start_session(), search() and create_memory() take as their domain argument.

Parameters:

timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The available domains and accompanying guidance.

Raises:

MemcoAPIError – If the service returns an error status.

Return type:

DomainList

Example

>>> for domain in client.memory.list_domains().domains:
...     print(domain.slug, "-", domain.summary)
list_tools(*, timeout=None)[source]

Every method this contract declares, and which of them your token’s role permits.

The catalog itself never varies; only availability does. Availability names a permission, not a guarantee: a method reported available may still be refused for a reason unrelated to role, such as a memory domain with no network provisioned for it.

start_session() calls this once per session and caches the result, which is what Session.tools() filters against – so calling this directly is for a caller that wants the catalog itself, not for shaping what a session offers.

Parameters:

timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

One descriptor per method the contract declares.

Raises:

MemcoAPIError – If the service returns an error status.

Return type:

tuple[ToolDescriptor, …]

Example

>>> {tool.name for tool in client.memory.list_tools() if tool.available}
start_session(domain, *, timeout=None)[source]

Start a session and get its id. A session groups the searches you make while working on one task, so they are recorded as the series they are rather than as unrelated one-offs.

Call when: at the start of work that will involve multiple related searches, or when you want a stable session id to reuse across search(), share_feedback(), and enrich_memory(). Pass the id as session_id to every search you make for it — and to share_feedback() and enrich_memory(). A session stays usable for as long as you keep naming it.

Parameters:
  • domain (str) – (Required) The memory domain to operate in. Call list_domains() for the domains available to you.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The open session, with every session-bound operation already applied – with_session() returns the same kind of object.

Raises:
Return type:

Session

Example

>>> session = client.memory.start_session("coding")
>>> session.id
'session-z2ye39'
with_session(domain, *, timeout=None)[source]

Open a session and apply it to every call made through the result.

The same as start_session(): kept as its own name for the context-manager call site, wherever the session outlives a line or two. A call that silently drops the id is still a valid call, it just stops being part of the series.

Parameters:
  • domain (str) – Slug of the domain, as returned by list_domains().

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The open session, with every session-bound operation already applied – the same as what start_session() returns.

Raises:
Return type:

Session

Example

>>> with client.memory.with_session("coding") as session:
...     result = session.search("how does X work")
search(query, *, domain=None, session_id=None, tags=None, timeout=None)[source]

Search Memco Shared Memory for existing knowledge before working a problem out from scratch. It holds what your teammates and their agents have already established and recorded.

Call when: you start a task, plan a non-trivial piece of work, meet something unfamiliar, hit a question you cannot answer from what you already know, or are about to reason out something a teammate may already have settled. Search first, then work.

Pass either a domain or a session_id — a search naming neither is refused. Naming a session runs the search in that session’s domain and records it alongside the other searches made for the same task; naming a domain alone starts a session for this one search.

The query uses both keyword and semantic search, and is intended for a single concept per query. If you need varied information, make multiple queries.

Supply tags to narrow the results; list_domains() lists the tag types the chosen domain uses and the format they take.

Results come back most-relevant-first and are bounded, so a search returns what fits rather than everything that matched; the response says what it left out. Memories are written by your teammates and their agents. Within one session a result already returned is not repeated — it comes back as a reference to the idx that carried it, which get_memory() turns back into content.

Parameters:
  • query (str) – (Required) A task-based query from the user such as a question, statement, or task description. To ensure readability, use markdown formatting. At most 1000 characters.

  • domain (str | None) – The memory domain to search in. Required unless you pass session_id, which supplies the domain of the session it names. Call list_domains() for the domains available to you.

  • session_id (str | None) – The session to record this search under, as returned by start_session() or a previous search. The search runs in that session’s memory domain, so the domain argument is not needed and is ignored. Omit this to start a new session, in which case a domain is required.

  • tags (Iterable[Tag] | None) – Tags narrowing or boosting the results. Which types narrow rather than boost is per-domain; list_domains() describes them.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The memories selected, with guidance on adding to and rating them.

Raises:
Return type:

SearchResult[Memory]

Example

>>> result = client.memory.search(
...     "how should a client authenticate against the memory API",
...     domain="coding",
...     tags=[Tag(type="language", value="python", version="3.12")],
... )
>>> for memory in result.memories:
...     for insight in memory.insights:
...         print(insight.title, insight.updated)
get_memory(idx, *, timeout=None)[source]

Fetch one memory a search returned, by its idx, and get it back in full.

Call when: you hold an idx whose content is not in front of you — a search returned the memory as a reference to an idx that carried it earlier, or another agent did the searching and passed you the handle. An insight’s idx returns the memory holding it.

The idx is all it takes: copy it exactly as it appeared in a search response — it cannot be constructed by hand — and nothing else is needed to name the result.

When a result shows a ref instead of content, ask by the value in its own idx, never the value in its ref. A result rendered as <memory idx=”memory-THIS-1” ref=”memory-EARLIER-1”> is fetched with “memory-THIS-1”: the ref says where the content was delivered, not what to ask for. Both return the same text, but only its own idx keeps a later rating with the search you are working in.

Parameters:
  • idx (str) – (Required) The idx of the result to fetch, copied exactly as it appeared in a search response. An insight’s idx returns the memory holding it.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The memory and its insights.

Raises:
Return type:

Memory

Example

>>> memory = client.memory.get_memory("memory-9fg6vc-1")
>>> [insight.title for insight in memory.insights]
create_memory(*, query, title, content, domain=None, session_id=None, tags=None, source=DataSource.AGENT, timeout=None)[source]

Save new knowledge to Memco Shared Memory, where your teammates and their agents will find it.

Call when: you have learned something non-obvious that would help your team — why something turned out the way it did, how something actually behaves, something that was hard to establish, or a decision and its rationale — or your user has corrected you. Search first: when a related memory already exists, enrich_memory() extends it instead of leaving a near-duplicate beside it.

Pass either a domain or a session_id — a call naming neither is refused. Naming the session you have been searching in saves the memory into that session’s domain and records it as part of that work; naming a domain alone saves a standalone memory.

Each memory needs a query (what someone would search to find this), a title, and content describing what you learned. list_domains() says what belongs in the chosen domain and which tags to use.

Parameters:
  • query (str) – (Required) A query describing what someone would search to find this memory, such as a question or problem statement. Use markdown formatting for readability. At most 1000 characters.

  • title (str) – (Required) A short title describing what this memory is about. Title and content together must be at most 5000 characters.

  • content (str) – (Required) The knowledge to save. Should be a concise, non-trivial finding that others can learn from. Supports markdown formatting. Title and content together must be at most 5000 characters; split a longer finding across several memories.

  • domain (str | None) – The memory domain to save into. Required unless you pass session_id, which supplies the domain of the session it names. Call list_domains() for the domains available to you.

  • session_id (str | None) – The session this memory was learned during, as returned by start_session() or a previous search. It records the memory as part of that series of work, and supplies the memory domain, so the domain argument is not needed and is ignored. Omit it to save a standalone memory.

  • tags (Iterable[Tag] | None) – Tags describing the subject and context.

  • source (DataSource) – Who produced the content. Defaults to AGENT.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The accepted write, whose operation_id is None if the write was accepted but cannot be undone.

Raises:
Return type:

WriteResult

Example

>>> result = client.memory.create_memory(
...     query="how do I authenticate against the memory API",
...     title="Memory API takes a Bearer token",
...     content="The prefix is case-sensitive: lowercase 'bearer' is rejected.",
...     session_id=session.id,
...     tags=[Tag(type="language", value="python")],
... )
>>> result.operation_id
'create-8fj2k1'
enrich_memory(*, memory_idx, session_id, title, content, tags=None, sources=None, source=DataSource.AGENT, timeout=None)[source]

Add information to an existing memory in Memco Shared Memory, so your finding lands beside the one it belongs to rather than in a memory that competes with it.

Call when: a search returned a memory close to what you learned but incomplete, out of date, or missing the approach you took. Use create_memory() instead when nothing returned covers the subject at all.

Set memory_idx to the memory you want to extend (from search results), or ‘new’ to add a standalone addition. Keep an addition concise and say only what is not already there. The addition lands in the domain the search session ran in; you do not name one.

Parameters:
  • memory_idx (str) – (Required) The memory_idx of the memory you are enriching. If you are adding to a new memory, set memory_idx to ‘new’.

  • session_id (str) – (Required) The session id you are enriching a memory in. The ID was included in the response from search().

  • title (str) – (Required) A short title describing what you learned. Title and content together must be at most 5000 characters.

  • content (str) – (Required) The knowledge you want to add. Use markdown formatting for readability. Title and content together must be at most 5000 characters; split a longer finding across several enrichments.

  • tags (Iterable[Tag] | None) – Tags describing the addition.

  • sources (Iterable[str] | None) – A list of memories received from Memco Shared Memory that proved helpful in reaching this insight. Up to 20 sources can be included.

  • source (DataSource) – Who produced the content. Defaults to AGENT.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The accepted write.

Raises:
Return type:

WriteResult

Example

>>> client.memory.enrich_memory(
...     memory_idx="memory-9fg6vc-2",
...     session_id=session.id,
...     title="A connection check does not prove the credential works",
...     content="That check carries no credential, so a bad token surfaces later.",
... )
share_feedback(*, session_id, feedback, timeout=None)[source]

Rate the relevance and correctness of search results. Only you can tell whether a result answered the query, and these ratings shape which results are shown next.

Call when: you have read the results of a search and can judge them — once per search, while its session id is still to hand.

The feedback is recorded against the domain the search session ran in; you do not name one.

Parameters:
  • session_id (str) – (Required) The session you are providing feedback for. The ID was included in the response from search().

  • feedback (Iterable[FeedbackRating]) – One rating per result. Each handle must be copied exactly from a search result; a memory’s own handle rates every insight under it.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The ratings that were recorded, each with any advice it earned.

Raises:
Return type:

FeedbackResult

Example

>>> client.memory.share_feedback(
...     session_id=session.id,
...     feedback=[
...         FeedbackRating(idx="memory-9fg6vc-2-insight-1",
...                        relevant=True, correct=True),
...     ],
... )
revert_memory(operation_id, *, timeout=None)[source]

Undo a memory you just wrote, using the operation id that create_memory() or enrich_memory() returned.

Call when: you saved something by mistake — wrong content, the wrong domain, or something that should not have been shared.

Your entry is always removed. The memory it belongs to is removed with it only when your entry was the last one in it — so reverting a create_memory(), or an enrich_memory() you sent with memory_idx ‘new’, removes that memory too, while reverting an addition to a memory that holds other entries leaves the memory in place. You can only revert your own writes, and only within 2 days.

Parameters:
  • operation_id (str) – (Required) The operation id returned by the create_memory() or enrich_memory() call you want to undo, for example ‘create-hpc08-1’.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

What the revert actually removed.

Raises:
Return type:

RevertResult

Example

>>> result = client.memory.revert_memory("create-8fj2k1")
>>> if result.outcome is RevertOutcome.EXPIRED:
...     print("outside the revert window")
import_memories(memories, *, domain=None, session_id=None, timeout=None)[source]

Fill a new or nearly empty workspace with the knowledge a team already holds, in one call, so memory starts out useful instead of empty.

Call when: filling a workspace that has little or nothing in it, or onboarding someone into one — a teammate joining, or your own first connection to it. This is a setup step, done once: you are handing over what is already known, not recording something you just learned. Use create_memory() for a single finding from this session.

Pass either a domain or a session_id — a call naming neither is refused. Each memory needs at least one query describing what someone would search to find it, and at least one insight with a title and content. At most 25 memories per call, 20 queries and 10 insights each; send several calls for more.

Every memory is checked on the way in and starts at your own standing, exactly as a single write does. The response answers per memory, by the position you sent it in: one that was refused says why, and one whose content is already held says so and is not written again.

Parameters:
  • memories (Iterable[ImportedMemory]) – (Required) The memories to contribute. At least one, at most 25 per call; send several calls for more.

  • domain (str | None) – The memory domain to import into. Required unless you pass session_id, which supplies the domain of the session it names. Call list_domains() for the domains available to you.

  • session_id (str | None) – The session these memories were contributed during, as returned by start_session() or a previous search. It records them as part of that series of work, and supplies the memory domain, so the domain argument is not needed and is ignored.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

One outcome per memory submitted, in the order they were sent.

Raises:
  • MemcoInvalidRequestError – If the batch is empty, if an entry is invalid or exceeds a reported per-entry cap, or if neither a domain nor a session was given.

  • MemcoAPIError – If the service returns an error status.

Return type:

ImportResult

Example

>>> result = client.memory.import_memories(
...     [
...         ImportedMemory(
...             queries=["how do I authenticate against the memory API"],
...             insights=[ImportedInsight(title="Bearer is case-sensitive",
...                                       content="Lowercase 'bearer' is rejected.")],
...             tags=[Tag(type="language", value="python")],
...         )
...     ],
...     domain="coding",
... )
>>> [(o.index, o.status.name) for o in result.results]
[(0, 'QUEUED')]
class AsyncMemoryOperations(stub, call)[source]

Bases: object

The memory operations, on an asyncio client.

Reached as memory; not constructed directly. Mirrors MemoryOperations method for method.

Example

>>> async with AsyncMemco() as client:
...     session = await client.memory.start_session("coding")
...     result = await session.search("how does X work")
Parameters:
  • stub (Any)

  • call (Callable[..., Any])

async list_domains(*, timeout=None)[source]

List the memory domains available to you and describe each one: what it holds, when to search it, what belongs in it and what does not, and the tag vocabulary and format it uses.

Call when: before your first search or write of a task, and whenever you are unsure which domain a question or a finding belongs to. The slug you choose is what start_session(), search() and create_memory() take as their domain argument.

Parameters:

timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The available domains and accompanying guidance.

Raises:

MemcoAPIError – If the service returns an error status.

Return type:

DomainList

Example

>>> for domain in (await client.memory.list_domains()).domains:
...     print(domain.slug, "-", domain.summary)
async list_tools(*, timeout=None)[source]

Every method this contract declares, and which of them your token’s role permits.

The catalog itself never varies; only availability does. Availability names a permission, not a guarantee: a method reported available may still be refused for a reason unrelated to role, such as a memory domain with no network provisioned for it.

start_session() calls this once per session and caches the result, which is what AsyncSession.tools() filters against – so calling this directly is for a caller that wants the catalog itself, not for shaping what a session offers.

Parameters:

timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

One descriptor per method the contract declares.

Raises:

MemcoAPIError – If the service returns an error status.

Return type:

tuple[ToolDescriptor, …]

Example

>>> {tool.name for tool in await client.memory.list_tools() if tool.available}
async start_session(domain, *, timeout=None)[source]

Start a session and get its id. A session groups the searches you make while working on one task, so they are recorded as the series they are rather than as unrelated one-offs.

Call when: at the start of work that will involve multiple related searches, or when you want a stable session id to reuse across search(), share_feedback(), and enrich_memory(). Pass the id as session_id to every search you make for it — and to share_feedback() and enrich_memory(). A session stays usable for as long as you keep naming it.

Parameters:
  • domain (str) – (Required) The memory domain to operate in. Call list_domains() for the domains available to you.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The open session, with every session-bound operation already applied – with_session() returns the same kind of object.

Raises:
Return type:

AsyncSession

Example

>>> session = await client.memory.start_session("coding")
>>> session.id
'session-z2ye39'
with_session(domain, *, timeout=None)[source]

Open a session and apply it to every call made through the result.

The same as start_session(): kept as its own name for the context-manager call site, wherever the session outlives a line or two. A call that silently drops the id is still a valid call, it just stops being part of the series.

The result is both awaitable and an async context manager, so await and async with both reach the session. Nothing is sent until one of them opens it, unlike the synchronous form, which opens it as it is called.

Parameters:
  • domain (str) – Slug of the domain, as returned by list_domains().

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

A handle that opens the session and yields it, on await or on entering it.

Raises:
Return type:

AsyncSessionOpener

Example

>>> async with client.memory.with_session("coding") as session:
...     result = await session.search("how does X work")
async search(query, *, domain=None, session_id=None, tags=None, timeout=None)[source]

Search Memco Shared Memory for existing knowledge before working a problem out from scratch. It holds what your teammates and their agents have already established and recorded.

Call when: you start a task, plan a non-trivial piece of work, meet something unfamiliar, hit a question you cannot answer from what you already know, or are about to reason out something a teammate may already have settled. Search first, then work.

Pass either a domain or a session_id — a search naming neither is refused. Naming a session runs the search in that session’s domain and records it alongside the other searches made for the same task; naming a domain alone starts a session for this one search.

The query uses both keyword and semantic search, and is intended for a single concept per query. If you need varied information, make multiple queries.

Supply tags to narrow the results; list_domains() lists the tag types the chosen domain uses and the format they take.

Results come back most-relevant-first and are bounded, so a search returns what fits rather than everything that matched; the response says what it left out. Memories are written by your teammates and their agents. Within one session a result already returned is not repeated — it comes back as a reference to the idx that carried it, which get_memory() turns back into content.

Parameters:
  • query (str) – (Required) A task-based query from the user such as a question, statement, or task description. To ensure readability, use markdown formatting. At most 1000 characters.

  • domain (str | None) – The memory domain to search in. Required unless you pass session_id, which supplies the domain of the session it names. Call list_domains() for the domains available to you.

  • session_id (str | None) – The session to record this search under, as returned by start_session() or a previous search. The search runs in that session’s memory domain, so the domain argument is not needed and is ignored. Omit this to start a new session, in which case a domain is required.

  • tags (Iterable[Tag] | None) – Tags narrowing or boosting the results. Which types narrow rather than boost is per-domain; list_domains() describes them.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The memories selected, with guidance on adding to and rating them.

Raises:
Return type:

SearchResult[AsyncMemory]

Example

>>> result = await client.memory.search(
...     "how should a client authenticate against the memory API",
...     domain="coding",
...     tags=[Tag(type="language", value="python", version="3.12")],
... )
>>> for memory in result.memories:
...     for insight in memory.insights:
...         print(insight.title, insight.updated)
async get_memory(idx, *, timeout=None)[source]

Fetch one memory a search returned, by its idx, and get it back in full.

Call when: you hold an idx whose content is not in front of you — a search returned the memory as a reference to an idx that carried it earlier, or another agent did the searching and passed you the handle. An insight’s idx returns the memory holding it.

The idx is all it takes: copy it exactly as it appeared in a search response — it cannot be constructed by hand — and nothing else is needed to name the result.

When a result shows a ref instead of content, ask by the value in its own idx, never the value in its ref. A result rendered as <memory idx=”memory-THIS-1” ref=”memory-EARLIER-1”> is fetched with “memory-THIS-1”: the ref says where the content was delivered, not what to ask for. Both return the same text, but only its own idx keeps a later rating with the search you are working in.

Parameters:
  • idx (str) – (Required) The idx of the result to fetch, copied exactly as it appeared in a search response. An insight’s idx returns the memory holding it.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The memory and its insights.

Raises:
Return type:

AsyncMemory

Example

>>> memory = await client.memory.get_memory("memory-9fg6vc-1")
>>> [insight.title for insight in memory.insights]
async create_memory(*, query, title, content, domain=None, session_id=None, tags=None, source=DataSource.AGENT, timeout=None)[source]

Save new knowledge to Memco Shared Memory, where your teammates and their agents will find it.

Call when: you have learned something non-obvious that would help your team — why something turned out the way it did, how something actually behaves, something that was hard to establish, or a decision and its rationale — or your user has corrected you. Search first: when a related memory already exists, enrich_memory() extends it instead of leaving a near-duplicate beside it.

Pass either a domain or a session_id — a call naming neither is refused. Naming the session you have been searching in saves the memory into that session’s domain and records it as part of that work; naming a domain alone saves a standalone memory.

Each memory needs a query (what someone would search to find this), a title, and content describing what you learned. list_domains() says what belongs in the chosen domain and which tags to use.

Parameters:
  • query (str) – (Required) A query describing what someone would search to find this memory, such as a question or problem statement. Use markdown formatting for readability. At most 1000 characters.

  • title (str) – (Required) A short title describing what this memory is about. Title and content together must be at most 5000 characters.

  • content (str) – (Required) The knowledge to save. Should be a concise, non-trivial finding that others can learn from. Supports markdown formatting. Title and content together must be at most 5000 characters; split a longer finding across several memories.

  • domain (str | None) – The memory domain to save into. Required unless you pass session_id, which supplies the domain of the session it names. Call list_domains() for the domains available to you.

  • session_id (str | None) – The session this memory was learned during, as returned by start_session() or a previous search. It records the memory as part of that series of work, and supplies the memory domain, so the domain argument is not needed and is ignored. Omit it to save a standalone memory.

  • tags (Iterable[Tag] | None) – Tags describing the subject and context.

  • source (DataSource) – Who produced the content. Defaults to AGENT.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The accepted write, whose operation_id is None if the write was accepted but cannot be undone.

Raises:
Return type:

WriteResult

Example

>>> result = await client.memory.create_memory(
...     query="how do I authenticate against the memory API",
...     title="Memory API takes a Bearer token",
...     content="The prefix is case-sensitive: lowercase 'bearer' is rejected.",
...     session_id=session.id,
...     tags=[Tag(type="language", value="python")],
... )
>>> result.operation_id
'create-8fj2k1'
async enrich_memory(*, memory_idx, session_id, title, content, tags=None, sources=None, source=DataSource.AGENT, timeout=None)[source]

Add information to an existing memory in Memco Shared Memory, so your finding lands beside the one it belongs to rather than in a memory that competes with it.

Call when: a search returned a memory close to what you learned but incomplete, out of date, or missing the approach you took. Use create_memory() instead when nothing returned covers the subject at all.

Set memory_idx to the memory you want to extend (from search results), or ‘new’ to add a standalone addition. Keep an addition concise and say only what is not already there. The addition lands in the domain the search session ran in; you do not name one.

Parameters:
  • memory_idx (str) – (Required) The memory_idx of the memory you are enriching. If you are adding to a new memory, set memory_idx to ‘new’.

  • session_id (str) – (Required) The session id you are enriching a memory in. The ID was included in the response from search().

  • title (str) – (Required) A short title describing what you learned. Title and content together must be at most 5000 characters.

  • content (str) – (Required) The knowledge you want to add. Use markdown formatting for readability. Title and content together must be at most 5000 characters; split a longer finding across several enrichments.

  • sources (Iterable[str] | None) – A list of memories received from Memco Shared Memory that proved helpful in reaching this insight. Up to 20 sources can be included.

  • tags (Iterable[Tag] | None) – Tags describing the addition.

  • source (DataSource) – Who produced the content. Defaults to AGENT.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The accepted write.

Raises:
Return type:

WriteResult

Example

>>> await client.memory.enrich_memory(
...     memory_idx="memory-9fg6vc-2",
...     session_id=session.id,
...     title="A connection check does not prove the credential works",
...     content="That check carries no credential, so a bad token surfaces later.",
... )
async share_feedback(*, session_id, feedback, timeout=None)[source]

Rate the relevance and correctness of search results. Only you can tell whether a result answered the query, and these ratings shape which results are shown next.

Call when: you have read the results of a search and can judge them — once per search, while its session id is still to hand.

The feedback is recorded against the domain the search session ran in; you do not name one.

Parameters:
  • session_id (str) – (Required) The session you are providing feedback for. The ID was included in the response from search().

  • feedback (Iterable[FeedbackRating]) – One rating per result. Each handle must be copied exactly from a search result; a memory’s own handle rates every insight under it.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The ratings that were recorded, each with any advice it earned.

Raises:
Return type:

FeedbackResult

Example

>>> await client.memory.share_feedback(
...     session_id=session.id,
...     feedback=[
...         FeedbackRating(idx="memory-9fg6vc-2-insight-1",
...                        relevant=True, correct=True),
...     ],
... )
async revert_memory(operation_id, *, timeout=None)[source]

Undo a memory you just wrote, using the operation id that create_memory() or enrich_memory() returned.

Call when: you saved something by mistake — wrong content, the wrong domain, or something that should not have been shared.

Your entry is always removed. The memory it belongs to is removed with it only when your entry was the last one in it — so reverting a create_memory(), or an enrich_memory() you sent with memory_idx ‘new’, removes that memory too, while reverting an addition to a memory that holds other entries leaves the memory in place. You can only revert your own writes, and only within 2 days.

Parameters:
  • operation_id (str) – (Required) The operation id returned by the create_memory() or enrich_memory() call you want to undo, for example ‘create-hpc08-1’.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

What the revert actually removed.

Raises:
Return type:

RevertResult

Example

>>> result = await client.memory.revert_memory("create-8fj2k1")
>>> if result.outcome is RevertOutcome.EXPIRED:
...     print("outside the revert window")
async import_memories(memories, *, domain=None, session_id=None, timeout=None)[source]

Fill a new or nearly empty workspace with the knowledge a team already holds, in one call, so memory starts out useful instead of empty.

Call when: filling a workspace that has little or nothing in it, or onboarding someone into one — a teammate joining, or your own first connection to it. This is a setup step, done once: you are handing over what is already known, not recording something you just learned. Use create_memory() for a single finding from this session.

Pass either a domain or a session_id — a call naming neither is refused. Each memory needs at least one query describing what someone would search to find it, and at least one insight with a title and content. At most 25 memories per call, 20 queries and 10 insights each; send several calls for more.

Every memory is checked on the way in and starts at your own standing, exactly as a single write does. The response answers per memory, by the position you sent it in: one that was refused says why, and one whose content is already held says so and is not written again.

Parameters:
  • memories (Iterable[ImportedMemory]) – (Required) The memories to contribute. At least one, at most 25 per call; send several calls for more.

  • domain (str | None) – The memory domain to import into. Required unless you pass session_id, which supplies the domain of the session it names. Call list_domains() for the domains available to you.

  • session_id (str | None) – The session these memories were contributed during, as returned by start_session() or a previous search. It records them as part of that series of work, and supplies the memory domain, so the domain argument is not needed and is ignored.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

One outcome per memory submitted, in the order they were sent.

Raises:
  • MemcoInvalidRequestError – If the batch is empty, if an entry is invalid or exceeds a reported per-entry cap, or if neither a domain nor a session was given.

  • MemcoAPIError – If the service returns an error status.

Return type:

ImportResult

Example

>>> result = await client.memory.import_memories(
...     [
...         ImportedMemory(
...             queries=["how do I authenticate against the memory API"],
...             insights=[ImportedInsight(title="Bearer is case-sensitive",
...                                       content="Lowercase 'bearer' is rejected.")],
...             tags=[Tag(type="language", value="python")],
...         )
...     ],
...     domain="coding",
... )
>>> [(o.index, o.status.name) for o in result.results]
[(0, 'QUEUED')]

Sessions

Returned by client.memory.start_session(...) and client.memory.with_session(...) alike; both hand back the same object, with every session-bound operation already applied.

class Session(operations, session_id, instructions, tool_catalog)[source]

Bases: object

An open session, with every session-bound memory operation applied.

Returned by MemoryOperations.start_session() and MemoryOperations.with_session() alike; not constructed directly. Every call made through it is recorded under the session it holds, so the id cannot be dropped, mistyped, or invented further down a call stack. The session supplies the domain too, which is why no operation here takes one.

Usable as a context manager, which releases nothing: the contract has no call that ends a session, and a session id stays usable for as long as it is named. The block bounds the scope for the reader rather than managing a resource.

Variables:
  • id – The session every call through this object names.

  • instructions – What the service said when the session was opened.

Parameters:

Example

>>> with client.memory.with_session("coding") as session:
...     result = session.search("how does X work")
...     session.share_feedback(feedback=[
...         FeedbackRating(idx=result.memories[0].idx,
...                        relevant=True, correct=True),
...     ])
property id: str

The session every call through this object names.

property instructions: Instructions

What the service said when the session was opened.

search(query, *, tags=None, timeout=None)[source]

Search Memco Shared Memory for existing knowledge before working a problem out from scratch. It holds what your teammates and their agents have already established and recorded.

Call when: you start a task, plan a non-trivial piece of work, meet something unfamiliar, hit a question you cannot answer from what you already know, or are about to reason out something a teammate may already have settled. Search first, then work.

Pass either a domain or a session_id — a search naming neither is refused. Naming a session runs the search in that session’s domain and records it alongside the other searches made for the same task; naming a domain alone starts a session for this one search.

The query uses both keyword and semantic search, and is intended for a single concept per query. If you need varied information, make multiple queries.

Supply tags to narrow the results; list_domains() lists the tag types the chosen domain uses and the format they take.

Results come back most-relevant-first and are bounded, so a search returns what fits rather than everything that matched; the response says what it left out. Memories are written by your teammates and their agents. Within one session a result already returned is not repeated — it comes back as a reference to the idx that carried it, which get_memory() turns back into content.

Parameters:
  • query (str) – (Required) A task-based query from the user such as a question, statement, or task description. To ensure readability, use markdown formatting. At most 1000 characters.

  • tags (Iterable[Tag] | None) – Tags narrowing or boosting the results. Which types narrow rather than boost is per-domain; MemoryOperations.list_domains() describes them.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The memories selected, with guidance on adding to and rating them.

Raises:
Return type:

SearchResult[Memory]

Example

>>> result = session.search(
...     "how should a client authenticate against the memory API",
...     tags=[Tag(type="language", value="python", version="3.12")],
... )
get_memory(idx, *, timeout=None)[source]

Fetch one memory a search returned, by its idx, and get it back in full.

Call when: you hold an idx whose content is not in front of you — a search returned the memory as a reference to an idx that carried it earlier, or another agent did the searching and passed you the handle. An insight’s idx returns the memory holding it.

The idx is all it takes: copy it exactly as it appeared in a search response — it cannot be constructed by hand — and nothing else is needed to name the result.

When a result shows a ref instead of content, ask by the value in its own idx, never the value in its ref. A result rendered as <memory idx=”memory-THIS-1” ref=”memory-EARLIER-1”> is fetched with “memory-THIS-1”: the ref says where the content was delivered, not what to ask for. Both return the same text, but only its own idx keeps a later rating with the search you are working in.

Parameters:
  • idx (str) – (Required) The idx of the result to fetch, copied exactly as it appeared in a search response. An insight’s idx returns the memory holding it.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The memory and its insights.

Raises:
Return type:

Memory

Example

>>> memory = session.get_memory("memory-9fg6vc-1")
>>> [insight.title for insight in memory.insights]
create_memory(*, query, title, content, tags=None, source=DataSource.AGENT, timeout=None)[source]

Save new knowledge to Memco Shared Memory, where your teammates and their agents will find it.

Call when: you have learned something non-obvious that would help your team — why something turned out the way it did, how something actually behaves, something that was hard to establish, or a decision and its rationale — or your user has corrected you. Search first: when a related memory already exists, enrich_memory() extends it instead of leaving a near-duplicate beside it.

Pass either a domain or a session_id — a call naming neither is refused. Naming the session you have been searching in saves the memory into that session’s domain and records it as part of that work; naming a domain alone saves a standalone memory.

Each memory needs a query (what someone would search to find this), a title, and content describing what you learned. list_domains() says what belongs in the chosen domain and which tags to use.

Parameters:
  • query (str) – (Required) A query describing what someone would search to find this memory, such as a question or problem statement. Use markdown formatting for readability. At most 1000 characters.

  • title (str) – (Required) A short title describing what this memory is about. Title and content together must be at most 5000 characters.

  • content (str) – (Required) The knowledge to save. Should be a concise, non-trivial finding that others can learn from. Supports markdown formatting. Title and content together must be at most 5000 characters; split a longer finding across several memories.

  • tags (Iterable[Tag] | None) – Tags describing the subject and context.

  • source (DataSource) – Who produced the content. Defaults to AGENT.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The accepted write, whose operation_id is None if the write was accepted but cannot be undone.

Raises:
Return type:

WriteResult

Example

>>> result = session.create_memory(
...     query="how do I authenticate against the memory API",
...     title="Memory API takes a Bearer token",
...     content="The prefix is case-sensitive: lowercase 'bearer' is rejected.",
... )
enrich_memory(*, memory_idx, title, content, tags=None, sources=None, source=DataSource.AGENT, timeout=None)[source]

Add information to an existing memory in Memco Shared Memory, so your finding lands beside the one it belongs to rather than in a memory that competes with it.

Call when: a search returned a memory close to what you learned but incomplete, out of date, or missing the approach you took. Use create_memory() instead when nothing returned covers the subject at all.

Set memory_idx to the memory you want to extend (from search results), or ‘new’ to add a standalone addition. Keep an addition concise and say only what is not already there. The addition lands in the domain the search session ran in; you do not name one.

Parameters:
  • memory_idx (str) – (Required) The memory_idx of the memory you are enriching. If you are adding to a new memory, set memory_idx to ‘new’.

  • title (str) – (Required) A short title describing what you learned. Title and content together must be at most 5000 characters.

  • content (str) – (Required) The knowledge you want to add. Use markdown formatting for readability. Title and content together must be at most 5000 characters; split a longer finding across several enrichments.

  • tags (Iterable[Tag] | None) – Tags describing the addition.

  • sources (Iterable[str] | None) – A list of memories received from Memco Shared Memory that proved helpful in reaching this insight. Up to 20 sources can be included.

  • source (DataSource) – Who produced the content. Defaults to AGENT.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The accepted write.

Raises:
Return type:

WriteResult

Example

>>> session.enrich_memory(
...     memory_idx="memory-9fg6vc-2",
...     title="A connection check does not prove the credential works",
...     content="That check carries no credential, so a bad token surfaces later.",
... )
share_feedback(*, feedback, timeout=None)[source]

Rate the relevance and correctness of search results. Only you can tell whether a result answered the query, and these ratings shape which results are shown next.

Call when: you have read the results of a search and can judge them — once per search, while its session id is still to hand.

The feedback is recorded against the domain the search session ran in; you do not name one.

Parameters:
  • feedback (Iterable[FeedbackRating]) – One rating per result. Each handle must be copied exactly from a search result; a memory’s own handle rates every insight under it.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The ratings that were recorded, each with any advice it earned.

Raises:
Return type:

FeedbackResult

Example

>>> session.share_feedback(feedback=[
...     FeedbackRating(idx="memory-9fg6vc-2-insight-1",
...                    relevant=True, correct=True),
... ])
revert_memory(operation_id, *, timeout=None)[source]

Undo a memory you just wrote, using the operation id that create_memory() or enrich_memory() returned.

Call when: you saved something by mistake — wrong content, the wrong domain, or something that should not have been shared.

Your entry is always removed. The memory it belongs to is removed with it only when your entry was the last one in it — so reverting a create_memory(), or an enrich_memory() you sent with memory_idx ‘new’, removes that memory too, while reverting an addition to a memory that holds other entries leaves the memory in place. You can only revert your own writes, and only within 2 days.

Parameters:
  • operation_id (str) – (Required) The operation id returned by the create_memory() or enrich_memory() call you want to undo, for example ‘create-hpc08-1’.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

What the revert actually removed.

Raises:
Return type:

RevertResult

Example

>>> result = session.revert_memory("create-8fj2k1")
>>> if result.outcome is RevertOutcome.EXPIRED:
...     print("outside the revert window")
import_memories(memories, *, timeout=None)[source]

Fill a new or nearly empty workspace with the knowledge a team already holds, in one call, so memory starts out useful instead of empty.

Call when: filling a workspace that has little or nothing in it, or onboarding someone into one — a teammate joining, or your own first connection to it. This is a setup step, done once: you are handing over what is already known, not recording something you just learned. Use create_memory() for a single finding from this session.

Pass either a domain or a session_id — a call naming neither is refused. Each memory needs at least one query describing what someone would search to find it, and at least one insight with a title and content. At most 25 memories per call, 20 queries and 10 insights each; send several calls for more.

Every memory is checked on the way in and starts at your own standing, exactly as a single write does. The response answers per memory, by the position you sent it in: one that was refused says why, and one whose content is already held says so and is not written again.

Parameters:
  • memories (Iterable[ImportedMemory]) – (Required) The memories to contribute. At least one, at most 25 per call; send several calls for more.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

One outcome per memory submitted, in the order they were sent.

Raises:
Return type:

ImportResult

Example

>>> result = session.import_memories(
...     [
...         ImportedMemory(
...             queries=["how do I authenticate against the memory API"],
...             insights=[ImportedInsight(title="Bearer is case-sensitive",
...                                       content="Lowercase 'bearer' is rejected.")],
...         )
...     ]
... )
>>> [(o.index, o.status.name) for o in result.results]
[(0, 'QUEUED')]
tools()[source]

This session’s operations, described and rendered for an LLM.

Each tool carries what the operation is for, a JSON Schema for its arguments, and a call that renders the result as text. Every one is bound to this session, so nothing a model sends can change which session a call is recorded under.

The toolset hands itself to a framework — to_langchain(), to_anthropic(), to_openai() — or runs what a model named with call(). See memcoai.agent.

An operation is included only when your token’s role permits it, as reported by list_tools() when this session was opened. This only shapes what is offered here — it does not gate calling a Session method directly.

Returns:

One tool per operation your role permits, as a Toolset.

Raises:

MemcoConfigError – If this package’s docstrings are unavailable, which is what running Python with -OO does. Every description is derived from them.

Return type:

Toolset

Example

>>> with client.memory.with_session("coding") as session:
...     create_agent(model, tools=session.tools().to_langchain())
class AsyncSession(operations, session_id, instructions, tool_catalog)[source]

Bases: object

An open session, with every session-bound memory operation applied, on an asyncio client.

Returned by AsyncMemoryOperations.start_session() and AsyncMemoryOperations.with_session() alike; not constructed directly. Mirrors Session method for method. Every call made through it is recorded under the session it holds, so the id cannot be dropped, mistyped, or invented further down a call stack. The session supplies the domain too, which is why no operation here takes one.

Usable as an async context manager, which releases nothing: the contract has no call that ends a session, and a session id stays usable for as long as it is named. The block bounds the scope for the reader rather than managing a resource.

Variables:
  • id – The session every call through this object names.

  • instructions – What the service said when the session was opened.

Parameters:

Example

>>> async with client.memory.with_session("coding") as session:
...     result = await session.search("how does X work")
property id: str

The session every call through this object names.

property instructions: Instructions

What the service said when the session was opened.

async search(query, *, tags=None, timeout=None)[source]

Search Memco Shared Memory for existing knowledge before working a problem out from scratch. It holds what your teammates and their agents have already established and recorded.

Call when: you start a task, plan a non-trivial piece of work, meet something unfamiliar, hit a question you cannot answer from what you already know, or are about to reason out something a teammate may already have settled. Search first, then work.

Pass either a domain or a session_id — a search naming neither is refused. Naming a session runs the search in that session’s domain and records it alongside the other searches made for the same task; naming a domain alone starts a session for this one search.

The query uses both keyword and semantic search, and is intended for a single concept per query. If you need varied information, make multiple queries.

Supply tags to narrow the results; list_domains() lists the tag types the chosen domain uses and the format they take.

Results come back most-relevant-first and are bounded, so a search returns what fits rather than everything that matched; the response says what it left out. Memories are written by your teammates and their agents. Within one session a result already returned is not repeated — it comes back as a reference to the idx that carried it, which get_memory() turns back into content.

Parameters:
  • query (str) – (Required) A task-based query from the user such as a question, statement, or task description. To ensure readability, use markdown formatting. At most 1000 characters.

  • tags (Iterable[Tag] | None) – Tags narrowing or boosting the results. Which types narrow rather than boost is per-domain; AsyncMemoryOperations.list_domains() describes them.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The memories selected, with guidance on adding to and rating them.

Raises:
Return type:

SearchResult[AsyncMemory]

Example

>>> result = await session.search(
...     "how should a client authenticate against the memory API",
...     tags=[Tag(type="language", value="python", version="3.12")],
... )
async get_memory(idx, *, timeout=None)[source]

Fetch one memory a search returned, by its idx, and get it back in full.

Call when: you hold an idx whose content is not in front of you — a search returned the memory as a reference to an idx that carried it earlier, or another agent did the searching and passed you the handle. An insight’s idx returns the memory holding it.

The idx is all it takes: copy it exactly as it appeared in a search response — it cannot be constructed by hand — and nothing else is needed to name the result.

When a result shows a ref instead of content, ask by the value in its own idx, never the value in its ref. A result rendered as <memory idx=”memory-THIS-1” ref=”memory-EARLIER-1”> is fetched with “memory-THIS-1”: the ref says where the content was delivered, not what to ask for. Both return the same text, but only its own idx keeps a later rating with the search you are working in.

Parameters:
  • idx (str) – (Required) The idx of the result to fetch, copied exactly as it appeared in a search response. An insight’s idx returns the memory holding it.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The memory and its insights.

Raises:
Return type:

AsyncMemory

Example

>>> memory = await session.get_memory("memory-9fg6vc-1")
>>> [insight.title for insight in memory.insights]
async create_memory(*, query, title, content, tags=None, source=DataSource.AGENT, timeout=None)[source]

Save new knowledge to Memco Shared Memory, where your teammates and their agents will find it.

Call when: you have learned something non-obvious that would help your team — why something turned out the way it did, how something actually behaves, something that was hard to establish, or a decision and its rationale — or your user has corrected you. Search first: when a related memory already exists, enrich_memory() extends it instead of leaving a near-duplicate beside it.

Pass either a domain or a session_id — a call naming neither is refused. Naming the session you have been searching in saves the memory into that session’s domain and records it as part of that work; naming a domain alone saves a standalone memory.

Each memory needs a query (what someone would search to find this), a title, and content describing what you learned. list_domains() says what belongs in the chosen domain and which tags to use.

Parameters:
  • query (str) – (Required) A query describing what someone would search to find this memory, such as a question or problem statement. Use markdown formatting for readability. At most 1000 characters.

  • title (str) – (Required) A short title describing what this memory is about. Title and content together must be at most 5000 characters.

  • content (str) – (Required) The knowledge to save. Should be a concise, non-trivial finding that others can learn from. Supports markdown formatting. Title and content together must be at most 5000 characters; split a longer finding across several memories.

  • tags (Iterable[Tag] | None) – Tags describing the subject and context.

  • source (DataSource) – Who produced the content. Defaults to AGENT.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The accepted write, whose operation_id is None if the write was accepted but cannot be undone.

Raises:
Return type:

WriteResult

Example

>>> result = await session.create_memory(
...     query="how do I authenticate against the memory API",
...     title="Memory API takes a Bearer token",
...     content="The prefix is case-sensitive: lowercase 'bearer' is rejected.",
... )
async enrich_memory(*, memory_idx, title, content, tags=None, sources=None, source=DataSource.AGENT, timeout=None)[source]

Add information to an existing memory in Memco Shared Memory, so your finding lands beside the one it belongs to rather than in a memory that competes with it.

Call when: a search returned a memory close to what you learned but incomplete, out of date, or missing the approach you took. Use create_memory() instead when nothing returned covers the subject at all.

Set memory_idx to the memory you want to extend (from search results), or ‘new’ to add a standalone addition. Keep an addition concise and say only what is not already there. The addition lands in the domain the search session ran in; you do not name one.

Parameters:
  • memory_idx (str) – (Required) The memory_idx of the memory you are enriching. If you are adding to a new memory, set memory_idx to ‘new’.

  • title (str) – (Required) A short title describing what you learned. Title and content together must be at most 5000 characters.

  • content (str) – (Required) The knowledge you want to add. Use markdown formatting for readability. Title and content together must be at most 5000 characters; split a longer finding across several enrichments.

  • tags (Iterable[Tag] | None) – Tags describing the addition.

  • sources (Iterable[str] | None) – A list of memories received from Memco Shared Memory that proved helpful in reaching this insight. Up to 20 sources can be included.

  • source (DataSource) – Who produced the content. Defaults to AGENT.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The accepted write.

Raises:
Return type:

WriteResult

Example

>>> await session.enrich_memory(
...     memory_idx="memory-9fg6vc-2",
...     title="A connection check does not prove the credential works",
...     content="That check carries no credential, so a bad token surfaces later.",
... )
async share_feedback(*, feedback, timeout=None)[source]

Rate the relevance and correctness of search results. Only you can tell whether a result answered the query, and these ratings shape which results are shown next.

Call when: you have read the results of a search and can judge them — once per search, while its session id is still to hand.

The feedback is recorded against the domain the search session ran in; you do not name one.

Parameters:
  • feedback (Iterable[FeedbackRating]) – One rating per result. Each handle must be copied exactly from a search result; a memory’s own handle rates every insight under it.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

The ratings that were recorded, each with any advice it earned.

Raises:
Return type:

FeedbackResult

Example

>>> await session.share_feedback(feedback=[
...     FeedbackRating(idx="memory-9fg6vc-2-insight-1",
...                    relevant=True, correct=True),
... ])
async revert_memory(operation_id, *, timeout=None)[source]

Undo a memory you just wrote, using the operation id that create_memory() or enrich_memory() returned.

Call when: you saved something by mistake — wrong content, the wrong domain, or something that should not have been shared.

Your entry is always removed. The memory it belongs to is removed with it only when your entry was the last one in it — so reverting a create_memory(), or an enrich_memory() you sent with memory_idx ‘new’, removes that memory too, while reverting an addition to a memory that holds other entries leaves the memory in place. You can only revert your own writes, and only within 2 days.

Parameters:
  • operation_id (str) – (Required) The operation id returned by the create_memory() or enrich_memory() call you want to undo, for example ‘create-hpc08-1’.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

What the revert actually removed.

Raises:
Return type:

RevertResult

Example

>>> result = await session.revert_memory("create-8fj2k1")
>>> if result.outcome is RevertOutcome.EXPIRED:
...     print("outside the revert window")
async import_memories(memories, *, timeout=None)[source]

Fill a new or nearly empty workspace with the knowledge a team already holds, in one call, so memory starts out useful instead of empty.

Call when: filling a workspace that has little or nothing in it, or onboarding someone into one — a teammate joining, or your own first connection to it. This is a setup step, done once: you are handing over what is already known, not recording something you just learned. Use create_memory() for a single finding from this session.

Pass either a domain or a session_id — a call naming neither is refused. Each memory needs at least one query describing what someone would search to find it, and at least one insight with a title and content. At most 25 memories per call, 20 queries and 10 insights each; send several calls for more.

Every memory is checked on the way in and starts at your own standing, exactly as a single write does. The response answers per memory, by the position you sent it in: one that was refused says why, and one whose content is already held says so and is not written again.

Parameters:
  • memories (Iterable[ImportedMemory]) – (Required) The memories to contribute. At least one, at most 25 per call; send several calls for more.

  • timeout (float | None) – Per-call deadline in seconds. Defaults to the client’s.

Returns:

One outcome per memory submitted, in the order they were sent.

Raises:
Return type:

ImportResult

Example

>>> result = await session.import_memories(
...     [
...         ImportedMemory(
...             queries=["how do I authenticate against the memory API"],
...             insights=[ImportedInsight(title="Bearer is case-sensitive",
...                                       content="Lowercase 'bearer' is rejected.")],
...         )
...     ]
... )
>>> [(o.index, o.status.name) for o in result.results]
[(0, 'QUEUED')]
tools()[source]

This session’s operations, described and rendered for an LLM.

Each tool carries what the operation is for, a JSON Schema for its arguments, and an awaitable call that renders the result as text. Every one is bound to this session, so nothing a model sends can change which session a call is recorded under.

The toolset hands itself to a framework — to_langchain(), to_anthropic(), to_openai() — or runs what a model named with call(). See memcoai.agent.

An operation is included only when your token’s role permits it, as reported by list_tools() when this session was opened. This only shapes what is offered here — it does not gate calling an AsyncSession method directly.

Returns:

One tool per operation your role permits, as a AsyncToolset.

Raises:

MemcoConfigError – If this package’s docstrings are unavailable, which is what running Python with -OO does. Every description is derived from them.

Return type:

AsyncToolset

Example

>>> async with client.memory.with_session("coding") as session:
...     create_agent(model, tools=session.tools().to_langchain())
class AsyncSessionOpener(operations, domain, timeout)[source]

Bases: object

A session that has not been opened yet, awaitable or entered.

with_session cannot both do I/O and be usable as async with without this: an async def would force async with await ... at every call site, which is the one shape the synchronous surface has no counterpart for. Opening is deferred to the await or the __aenter__, so a scope that is built and dropped costs no session.

Parameters: