Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ history.txt
.DS_Store
CLAUDE.md

build/
build/
.codegraph/
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,45 @@ from dotenv import load_dotenv
load_dotenv(override=True)
```

### Optional OpenViking agent memory

OpenViking can be attached as middleware to recall long-term context before an
agent run and commit messages and bounded tool activity after it. It does not
replace SpoonOS graph state, checkpoints, interrupts, authorization, or Mem0.

```bash
pip install -e '.[openviking]'

# Local server
export OPENVIKING_URL=http://localhost:1933

# Remote server (add the key supplied by the server operator)
export OPENVIKING_URL=https://memory.example.com
export OPENVIKING_API_KEY=your-api-key
```

```python
from spoon_ai.agents import SpoonReactAI
from spoon_ai.middleware import OpenVikingMemoryMiddleware

memory = OpenVikingMemoryMiddleware(
session_id="stable-conversation-id",
user="alice",
actor_peer_id="research-agent",
provider_timeout_seconds=5.0,
)

agent = SpoonReactAI(..., middleware=[memory])
```

Call `memory.close()` during application shutdown to flush queued commits and
release resources. A client passed through `client=` remains caller-owned and
is not closed by the middleware.

See `examples/openviking_memory_middleware_demo.py` for a complete runnable
example. OpenViking is disabled unless this middleware is explicitly added, and
service failures do not block the agent run.

## 🪙 x402 Payments

SpoonOS now ships with a first-class x402 integration, letting agents pay for external services and expose their own paywalled endpoints.
Expand Down
33 changes: 33 additions & 0 deletions examples/openviking_memory_middleware_demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Run a Spoon agent with optional OpenViking long-term memory.

Start an OpenViking server and set OPENVIKING_URL (plus OPENVIKING_API_KEY
for a remote server) before running this example.
"""

import asyncio

from spoon_ai.agents import SpoonReactAI
from spoon_ai.middleware import OpenVikingMemoryMiddleware


async def main() -> None:
memory = OpenVikingMemoryMiddleware(
# A stable session keeps memories connected across separate agent runs.
session_id="spoon-openviking-demo",
recall_limit=5,
)
agent = SpoonReactAI(
name="openviking-demo",
system_prompt="You are a concise assistant.",
middleware=[memory],
x402_enabled=False,
)
try:
await agent.initialize()
print(await agent.run("Remember that I prefer short answers."))
finally:
memory.close()


if __name__ == "__main__":
asyncio.run(main())
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ dependencies = [ # Complete dependencies from requirements.txt for out-of-the-bo
memory = [
"mem0ai>=0.0.1",
]
openviking = [
"openviking-sdk>=0.1.6,<0.2",
]

[project.urls]
"Homepage" = "https://github.com/XSpoonAi/spoon-core" # Project URL
Expand Down
9 changes: 9 additions & 0 deletions spoon_ai/middleware/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@
PlanStep,
)

from .openviking_memory import (
OpenVikingMemoryMiddleware,
create_openviking_memory_middleware,
)

__all__ = [
# Core classes
"AgentMiddleware",
Expand Down Expand Up @@ -162,4 +167,8 @@
"create_planning_middleware",
"Plan",
"PlanStep",

# OpenViking memory
"OpenVikingMemoryMiddleware",
"create_openviking_memory_middleware",
]
Loading
Loading