loki / plugins
AGENTS.md28 starsChanged 2 months agoMITView on GitHub
Applies on top of the root AGENTS.md. Authoring guide + canonical compat contract: website/docs/developer-guide/plugins/index.md. Per-kind guides: memory-provider-plugin.md, model-provider-plugin.md, context-engine-plugin.md, image-gen-provider-plugin.md, ... Plugins live in their own directory and work within the ABCs / hooks / ctx surface we provide. A plugin MUST NOT modify run_agent.py, cli.py, gateway/run.py, loki_cli/main.py, etc. If it needs a capability the framework lacks, widen the generic plugin surface (new hook, new ctx method) and have the plugin use it — never hardcode plugin-specific logic into core…
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,774 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository69 other files it gives its agents.
- agent/AGENTS.mdAGENTS.md
- AGENTS.mdAGENTS.md
- cron/AGENTS.mdAGENTS.md
- gateway/AGENTS.mdAGENTS.md
- loki_cli/AGENTS.mdAGENTS.md
- skills/AGENTS.mdAGENTS.md
- tools/AGENTS.mdAGENTS.md
- tui_gateway/AGENTS.mdAGENTS.md
- web/AGENTS.mdAGENTS.md
- llms-full.txtllms.txt
- apple-notesSkill
- apple-remindersSkill
- findmySkill
- imessageSkill
- claude-codeSkill
- codexSkill
- computer-useSkill
- loki-agentSkill
- opencodeSkill
- architecture-diagramSkill
- ascii-videoSkill
- baoyu-infographicSkill
- claude-designSkill
- design-mdSkill
- humanizerSkill
- manim-videoSkill
- p5jsSkill
- popular-web-designsSkill
- songwriting-and-ai-musicSkill
- sdlc-reviewSkill
- email-inbox-triageSkill
- himalayaSkill
- gif-searchSkill
- songseeSkill
- youtube-contentSkill
- obsidianSkill
- airtableSkill
- boxSkill
- document-to-action-itemsSkill
- docxSkill
- google-workspaceSkill
- mapsSkill
- meeting-action-itemsSkill
- notionSkill
- pdfSkill
- powerpointSkill
- product-price-monitorSkill
- teams-meeting-pipelineSkill
- weekly-review-planningSkill
- xlsxSkill
- arxivSkill
- competitor-news-monitorSkill
- grounded-citationsSkill
- llm-wikiSkill
- xurlSkill
- codebase-inspectionSkill
- dogfoodSkill
- githubSkill
- inspecting-loki-desktop-domSkill
- loki-agent-skill-authoringSkill
- The first 60 shown.
The file
We split this AGENTS.md into the rules it gives an agent
2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 11
If it needs a capability the framework lacks, widen the generic plugin surface (new hook, new ctx method) and have the plugin use it — …
- Very specific: line 68
Never remove or rename PluginContext methods.
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
plugins/ — plugin kinds, compat contract, in-tree policy
Applies on top of the root AGENTS.md. Authoring guide + canonical compat contract:
website/docs/developer-guide/plugins/index.md. Per-kind guides: memory-provider-plugin.md,
model-provider-plugin.md, context-engine-plugin.md, image-gen-provider-plugin.md, ...
Plugins never touch core (Teknium, May 2026)
Plugins live in their own directory and work within the ABCs / hooks / ctx surface we provide.
A plugin MUST NOT modify run_agent.py, cli.py, gateway/run.py, loki_cli/main.py, etc.
If it needs a capability the framework lacks, widen the generic plugin surface (new hook, new
ctx method) and have the plugin use it — never hardcode plugin-specific logic into core (PR #5295
removed 95 lines of hardcoded honcho argparse from main.py). Plugin setup goes through
loki memory setup → provider.post_setup(loki_home, config), never a parallel top-level
command. A hook with no concrete consumer is speculative infrastructure and is rejected (root).
What may live in this tree (policy)
- No new in-tree memory providers (May 2026).
plugins/memory/is closed (honcho, mem0, supermemory, byterover, hindsight, holographic, openviking, retaindb stay; bug fixes welcome). New backends ship as standalone repos implementing the sameMemoryProviderABC, discovered through the same path, integrated vialoki memory setup/post_setup(). - No new third-party-product plugins (June 2026). Observability/metrics backends, vendor SaaS
connectors, analytics dashboards, paid-service tie-ins ship as standalone plugin repos
(
~/.loki/plugins/or pip entry point) promoted in Discord#plugins-skills-and-skins. Reason: every absorbed product is our maintenance burden against a fast-moving core for a backend we don't own.observability/,kanban/,disk-cleanup/are precedent, not an invitation. Closing such a PR is a coupling decision, not a quality judgment. - Reference/docs-companion plugins (
example-dashboard,strike-freedom-cockpit,plugin-llm-example,plugin-llm-async-example) live inloki-example-plugins, not here.
Plugin catalog (plugin-catalog/, Sep 2026)
The ONLY discovery system for out-of-tree plugins. One YAML per entry, 40-hex SHA pin mandatory,
human-merged via PR (plugin-catalog/README.md = admission policy; plugin-catalog-ci.yml clones
each changed entry at its pin and runs loki plugins validate). removed.yaml is the kill list —
every install path (CLI, dashboard, TUI) refuses matches; only the CLI has a loud --allow-removed.
Code: loki_cli/plugin_catalog.py (loader, live refresh from
/docs/api/plugin-catalog.json published by the docs build, in-tree fallback),
loki_cli/plugins_cmd_catalog.py (resolution, .loki-catalog.json provenance sidecar,
search/info/validate, re-pin on update, dashboard/TUI payloads). Never add a second name index:
bare names resolve through the catalog or error.
Plugin kinds and their discovery systems
| Kind | Where | Discovery | Notes |
| General | plugins/<name>/, ~/.loki/plugins/, ./.loki/plugins/, pip entry points | PluginManager (loki_cli/plugins.py), later-wins | register(ctx) registers hooks (pre_tool_call, post_tool_call, pre_llm_call, post_llm_call, on_session_start, on_session_end), tools (ctx.register_tool), CLI subcommands (ctx.register_cli_command — argparse tree wired into loki at startup, no main.py change) |
| Memory provider | plugins/memory/<name>/ | plugins/memory/__init__.py: bundled → $LOKI_HOME/plugins/ → ./.loki/plugins/ (opt-in LOKI_ENABLE_PROJECT_PLUGINS) → loki_agent.memory_providers entry points; bundled-first | Activated by name via memory.provider, so a dropped-in dir must not shadow a shipped one (reverse of general later-wins). Enumerates without importing. Implements MemoryProvider ABC (agent/memory_provider.py), orchestrated by agent/memory_manager.py: sync_turn, prefetch, shutdown, optional post_setup. cli.py with register_cli(subparser) is wired by discover_plugin_cli_commands() — only for the ACTIVE provider, so loki --help stays clean |
| Model provider | plugins/model-providers/<name>/ | providers/__init__.py._discover_providers(), lazy, on first get_provider_profile()/list_providers(); bundled → $LOKI_HOME/plugins/model-providers/ → legacy providers/<name>.py | __init__.py calls providers.register_provider(ProviderProfile(...)) at load; last-writer-wins so a user plugin overrides a bundled profile. PluginManager records kind: model-provider manifests but does NOT import them (would double-instantiate); manifests without kind: are auto-coerced by source heuristic (register_provider + ProviderProfile) |
| Context engine / image-gen / others | plugins/context_engine/, plugins/image_gen/, ... | ABC + orchestrator + per-plugin directory | Plug into agent/context_engine.py, agent/image_gen_provider.py |
| Platform adapters | plugins/platforms/<name>/adapter.py | gateway | Token-lock and scoped-secret rules in gateway/AGENTS.md (irc, feishu are canonical) |
Discovery timing pitfall: discover_plugins() runs only as a side effect of importing
model_tools.py. Code that reads plugin state without importing model_tools.py first must call
discover_plugins() explicitly (idempotent). Hooks are invoked from model_tools.py (pre/post
tool) and run_agent.py (lifecycle). When a plugin changes a default, add a migration guard keyed
on an "existing config" signal (_explicitly_configured) so existing users keep the old default.
Native plugin compatibility contract (summary — canonical text in the docs page)
Compatibility is a behavior contract, not a monolithic PLUGIN_API_VERSION, a manifest-wide
native api: match, or version literals on unrelated payloads. Documented surfaces stay additive:
- Hook payload data is added as keyword fields; callbacks are signature-inspected so old narrow
signatures receive only the fields they declare and
**kwargscallbacks get the full payload. - Never remove or rename
PluginContextmethods; new parameters are optional with defaults and keyword-only where possible. - Unknown native manifest fields are ignored.
- New provider methods get default implementations; optional callback kwargs are signature-inspected, not forwarded unconditionally.
- A local schema version exists only for a capability with a wire or persisted contract, and old state/config/session replay is preserved or migrated.
- Deprecations: once-per-process warning, documented replacement + migration note, ≥ 2 subsequent minor releases before removal.
- Compat tests load frozen plugins through the real discovery path and assert outcomes — never exact registry/catalog counts, source-reading tests, or "a global version literal changed".
Sep 2026 decomposition compat window (ends 2026-09-14)
PR #102117 moved internals into <stem>_<topic> siblings. Old import paths resolve through
PLUGIN-COMPAT __getattr__ blocks (listed in COMPAT_MANIFEST.md / compat_manifest.json)
until loki_cli.plugin_compat.COMPAT_REMOVAL_DATE, when the commit that added them is reverted.
loki_cli/plugin_compat.py is the single source: scan_plugin (AST scan), compat_report
(hits across enabled external plugins, cached to LOKI_HOME/.plugin-compat-report.json,
refreshed by discovery), removal_in_effect, warn_once. Surfaces: CLI banner notice,
loki plugins compat (shows affected user plugins), loki doctor, post-update notices, the
TUI/Desktop plugins.compat_report RPC. After the date PluginManager skips a hitting plugin
unless plugins.allow_deprecated_imports: true. In-tree code and tests never use compat paths
(scripts/check_compat_pointers.py in CI; -W error::loki_cli.plugin_compat.LokiPluginCompatWarning).
External-plugin compat is handled ONCE here — never add per-PR re-export shims.
Tests
tests/plugins/. Load through real discovery with a temp LOKI_HOME; assert behaviour (tool
registered, hook fired with expected kwargs), not counts. Opt-in telemetry rule applies to plugins
too: no attribution tag ships by default (tests/plugins/memory/test_hindsight_provider.py).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

