Skip to main content

Zeno Things tools: list/add/complete @tool wrappers backed by things-sdk.

Project description

zeno-tools-things

Things 3 / Things Cloud @tool wrappers for the Zeno AI assistant framework, backed by things-sdk.

Three agent-callable tools:

  • things_list(when="today"|"inbox"|"anytime"|"someday") — read tasks
  • things_add(title, notes=None, when="inbox", deadline=None) — create a task
  • things_complete(uuid) — mark a task complete

A ThingsAccount owns one local SQLite mirror plus one Things Cloud HTTP client, with a TTL guard so a single conversational turn doesn't double-pull from the cloud.

Install

uv add 'zeno-framework[things]'

Set credentials in the environment:

export THINGS_EMAIL="you@example.com"
export THINGS_PASSWORD="..."

Wiring

import asyncio
import contextlib
from pathlib import Path

from zeno.agent import Agent
from zeno.app import ZenoApp
from zeno.channels.cli import CliChannel
from zeno.memory import ThreeLayer
from zeno.memory.sqlite.conversation_store import SqliteConversationStore
from zeno.memory.sqlite.session_store import SqliteSessionStore
from zeno.memory.sqlite.user_memory_store import SqliteUserMemoryStore
from zeno.providers.claude_sdk import ClaudeSDKProvider
from zeno.tools_things import (
    configure_things,
    things_add,
    things_complete,
    things_list,
)


async def amain() -> None:
    data = Path.home() / ".zeno"
    data.mkdir(parents=True, exist_ok=True)

    # Reads THINGS_EMAIL / THINGS_PASSWORD from the environment.
    account = configure_things(
        db_path=str(data / "things.db"),
        sync_ttl_seconds=60,
    )

    agent = Agent(
        name="root",
        instructions="You manage the user's Things tasks.",
        tools=[things_list, things_add, things_complete],
    )

    app = ZenoApp(
        agent=agent,
        memory=ThreeLayer(
            session=SqliteSessionStore(data / "sessions.db"),
            user_memory=SqliteUserMemoryStore(data / "user_memory.db"),
            knowledge=...,  # plug in zeno-chroma or zeno-qdrant
            conversation=SqliteConversationStore(data / "conversations.db"),
        ),
        channels=[CliChannel()],
        provider=ClaudeSDKProvider(),
    )

    try:
        await app.run()
    finally:
        with contextlib.suppress(Exception):
            await account.stop()


asyncio.run(amain())

configure_things(...) installs a process-wide handle. Apps that prefer per-Ctx wiring can set ctx.state["things"] = ThingsAccount(...) directly — the tools resolve ctx.state first and fall back to the global.

Grouping the tools as a SubAgent

If your root agent has many responsibilities, isolate Things behind a specialist:

from zeno.agent import Agent, SubAgent

things_agent = SubAgent(
    name="things",
    instructions=(
        "You manage the user's Things tasks. "
        "Use `things_list` to read, `things_add` to create, "
        "and `things_complete` to mark a task done."
    ),
    tools=[things_list, things_add, things_complete],
)

root = Agent(
    name="root",
    instructions="Delegate todo-related questions to the `things` sub-agent.",
    sub_agents=[things_agent],
)

Sub-agent dispatch works on ClaudeSDKProvider (Claude Agent SDK's Task tool). OpenAIProvider does not support sub-agents — ZenoApp.start() raises ProviderCapabilityError if you mix them.

Sync model

  • Reads: things_list calls pull_sync only if the last successful pull was outside the configured TTL (default 60 s). Back-to-back calls within the window reuse the cached SQLite state.
  • Writes: things_add and things_complete write locally then call push_sync immediately so changes show up on every Things device right away.

License

MIT — see LICENSE.

Part of the Zeno framework.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zeno_tools_things-1.1.0.tar.gz (12.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

zeno_tools_things-1.1.0-py3-none-any.whl (10.8 kB view details)

Uploaded Python 3

File details

Details for the file zeno_tools_things-1.1.0.tar.gz.

File metadata

  • Download URL: zeno_tools_things-1.1.0.tar.gz
  • Upload date:
  • Size: 12.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for zeno_tools_things-1.1.0.tar.gz
Algorithm Hash digest
SHA256 5059bd6a1b1eacaa265048c49116baa79d9896d36939f217df29fc914ebfcb13
MD5 4299ceb2953d18c3e05b8ad8830476bb
BLAKE2b-256 3d5e37a16b2dc35369b97bf43d0faae8bed0eefaa835cd3138d64ebca3250a42

See more details on using hashes here.

Provenance

The following attestation bundles were made for zeno_tools_things-1.1.0.tar.gz:

Publisher: publish.yml on nkootstra/zeno

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file zeno_tools_things-1.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for zeno_tools_things-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a3b4cec5cb9d1ba03ad0d97079da07642e1d1406cfc8532cfd7dc19078cdcee1
MD5 f485777c02c6568a74c4037c06ea142b
BLAKE2b-256 85dd1e0499f31cb6551ac53982761d2cb11e0390961aac246f6a3bf127ce7ce3

See more details on using hashes here.

Provenance

The following attestation bundles were made for zeno_tools_things-1.1.0-py3-none-any.whl:

Publisher: publish.yml on nkootstra/zeno

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page