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.0.2.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.0.2-py3-none-any.whl (10.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: zeno_tools_things-1.0.2.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.0.2.tar.gz
Algorithm Hash digest
SHA256 806f74b2f40bc0f0df8cf4f2b8230236ef400549567cf013432ab454528ee025
MD5 95852c584d20f462ef666903b7eb8159
BLAKE2b-256 266ca7795db8815aca4f998d49672b80c3c40606da06f9658b61bf2c6a8c2e43

See more details on using hashes here.

Provenance

The following attestation bundles were made for zeno_tools_things-1.0.2.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.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for zeno_tools_things-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7ce3caebfa284695a84d52ab5ed64ae19d243afe20477b2f84b9a68b764e609c
MD5 14a15252b867a8f6874cbdf467c87122
BLAKE2b-256 c253ef2a9e7b2c45c3b0c90c81ff57b98f6dc0c2cb29479e113c4121c362b2ff

See more details on using hashes here.

Provenance

The following attestation bundles were made for zeno_tools_things-1.0.2-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