zettcode-skills 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zettcode_skills-0.4.1/.gitignore +37 -0
- zettcode_skills-0.4.1/PKG-INFO +19 -0
- zettcode_skills-0.4.1/pyproject.toml +51 -0
- zettcode_skills-0.4.1/src/zettcode/skills/__init__.py +13 -0
- zettcode_skills-0.4.1/src/zettcode/skills/mentions.py +47 -0
- zettcode_skills-0.4.1/src/zettcode/skills/plugin.py +51 -0
- zettcode_skills-0.4.1/src/zettcode/skills/py.typed +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
**/.venv/
|
|
2
|
+
**/__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
.smoke/
|
|
8
|
+
.coverage
|
|
9
|
+
**/.pytest_cache/
|
|
10
|
+
**/.ruff_cache/
|
|
11
|
+
.zett-tool-output/
|
|
12
|
+
.env
|
|
13
|
+
.DS_Store
|
|
14
|
+
|
|
15
|
+
# viztracer writes its trace here by default.
|
|
16
|
+
/result.json
|
|
17
|
+
|
|
18
|
+
# The docs site: dependencies, build output, and VitePress' cache.
|
|
19
|
+
node_modules/
|
|
20
|
+
docs/.vitepress/dist/
|
|
21
|
+
docs/.vitepress/cache/
|
|
22
|
+
docs/.vitepress/.temp/
|
|
23
|
+
|
|
24
|
+
# The TypeScript client is built from its sources; only dist/ is published.
|
|
25
|
+
clients/typescript/dist/
|
|
26
|
+
|
|
27
|
+
# The gateway's page is built from clients/gateway into the package when a distribution is made (`make gateway-ui`);
|
|
28
|
+
# the build output is not kept in the repository. pyproject's `artifacts` puts it in the wheel all the same.
|
|
29
|
+
packages/zettcode-gateway/src/zettcode/gateway/static/
|
|
30
|
+
|
|
31
|
+
# The palette gallery is generated by `make palettes`: every widget painted in
|
|
32
|
+
# every palette, written by docs/scripts/palette_gallery.py. Regenerate it
|
|
33
|
+
# rather than committing a 2 MB copy that goes stale the moment a colour moves.
|
|
34
|
+
docs/internal/palettes.html
|
|
35
|
+
|
|
36
|
+
# The release order is generated from the pyproject.toml files (`make order`); it is not kept in git.
|
|
37
|
+
packages/order.txt
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: zettcode-skills
|
|
3
|
+
Version: 0.4.1
|
|
4
|
+
Summary: The skills of ZettCode: the @ references and the tool that lets the model read one, as a part of the agent that lives apart from it
|
|
5
|
+
Project-URL: Repository, https://github.com/Chang-LeHung/zettcode
|
|
6
|
+
Author: Chang-LeHung
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Keywords: agent,skills,zettcode
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
16
|
+
Classifier: Typing :: Typed
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Requires-Dist: zett-agent<0.3,>=0.2.7
|
|
19
|
+
Requires-Dist: zettcode-engine
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "zettcode-skills"
|
|
3
|
+
description = "The skills of ZettCode: the @ references and the tool that lets the model read one, as a part of the agent that lives apart from it"
|
|
4
|
+
requires-python = ">=3.10"
|
|
5
|
+
dynamic = ["version"]
|
|
6
|
+
license = "MIT"
|
|
7
|
+
authors = [{name = "Chang-LeHung"}]
|
|
8
|
+
keywords = ["zettcode", "skills", "agent"]
|
|
9
|
+
classifiers = [
|
|
10
|
+
"Development Status :: 5 - Production/Stable",
|
|
11
|
+
"Programming Language :: Python :: 3.10",
|
|
12
|
+
"Programming Language :: Python :: 3.11",
|
|
13
|
+
"Programming Language :: Python :: 3.12",
|
|
14
|
+
"Programming Language :: Python :: 3.13",
|
|
15
|
+
"Programming Language :: Python :: 3.14",
|
|
16
|
+
"Programming Language :: Python :: 3.15",
|
|
17
|
+
"Typing :: Typed",
|
|
18
|
+
]
|
|
19
|
+
dependencies = [
|
|
20
|
+
# The plugin base classes and the shape of an @ reference.
|
|
21
|
+
"zettcode-engine",
|
|
22
|
+
# The skill extension that discovers and reads them.
|
|
23
|
+
"zett-agent>=0.2.7,<0.3",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
# Parts of the program, not plugins: the `zettcode.plugins` group is what the plugin release line looks for. They are
|
|
27
|
+
# activated with the agent's other parts and `[skills] enabled` is what turns them off.
|
|
28
|
+
[project.entry-points."zettcode.agent"]
|
|
29
|
+
skills = "zettcode.skills.plugin:SkillResources"
|
|
30
|
+
skill-tool = "zettcode.skills.plugin:SkillTool"
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Repository = "https://github.com/Chang-LeHung/zettcode"
|
|
34
|
+
|
|
35
|
+
[build-system]
|
|
36
|
+
requires = ["hatchling"]
|
|
37
|
+
build-backend = "hatchling.build"
|
|
38
|
+
|
|
39
|
+
[tool.hatch.version]
|
|
40
|
+
# One version for the whole repository: the engine ships the file.
|
|
41
|
+
path = "../zettcode-engine/src/zettcode/version.py"
|
|
42
|
+
|
|
43
|
+
[tool.hatch.build.targets.wheel]
|
|
44
|
+
packages = ["src/zettcode"]
|
|
45
|
+
|
|
46
|
+
[tool.hatch.build.targets.sdist]
|
|
47
|
+
include = ["/src", "/pyproject.toml"]
|
|
48
|
+
|
|
49
|
+
[tool.pytest.ini_options]
|
|
50
|
+
testpaths = ["tests"]
|
|
51
|
+
asyncio_mode = "auto"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""The skills of ZettCode: the ``@`` provider that offers them to the composer, and the extension that lists them for
|
|
2
|
+
the model and lets it read one.
|
|
3
|
+
|
|
4
|
+
A part of the program that lives in a distribution of its own, found through the ``zettcode.agent`` entry point and
|
|
5
|
+
activated with the agent's other parts. ``[skills] enabled`` in the configuration is what turns it off.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from .mentions import SkillMentions
|
|
11
|
+
from .plugin import SkillResources, SkillTool
|
|
12
|
+
|
|
13
|
+
__all__ = ["SkillMentions", "SkillResources", "SkillTool"]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""The ``@`` provider for skills."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Sequence
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from zett_agent.extensions.skill import SkillExtension
|
|
9
|
+
|
|
10
|
+
from zettcode.mention import Mention, MentionProvider
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SkillMentions(MentionProvider):
|
|
14
|
+
"""Skills discovered from the configured roots, named for the model to load."""
|
|
15
|
+
|
|
16
|
+
kind = "skill"
|
|
17
|
+
#: A skill is the more specific thing to mean when a repository holds a file of the same name, so it is asked
|
|
18
|
+
#: ahead of the files whatever order the plugins were registered in (a session still goes first).
|
|
19
|
+
precedence = -10
|
|
20
|
+
|
|
21
|
+
def __init__(self, roots: Sequence[Path]) -> None:
|
|
22
|
+
"""Discover skills once, the same way the agent's skill extension does."""
|
|
23
|
+
self._skills = {skill.name: skill for skill in SkillExtension(roots).skills}
|
|
24
|
+
|
|
25
|
+
def candidates(self, query: str) -> Sequence[Mention]:
|
|
26
|
+
"""List the discovered skills whose name starts with ``query``."""
|
|
27
|
+
return tuple(
|
|
28
|
+
Mention(token=f"@{skill.name}", kind=self.kind, name=skill.name, description=skill.description)
|
|
29
|
+
for skill in self._skills.values()
|
|
30
|
+
if skill.name.startswith(query)
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
def expand(self, name: str) -> str | None:
|
|
34
|
+
"""Name the skill and leave loading its instructions to the model.
|
|
35
|
+
|
|
36
|
+
The system prompt already catalogs every skill, and ``read_skill`` loads
|
|
37
|
+
the file, so the message only has to say which one the user meant;
|
|
38
|
+
inlining the body would spend context on instructions that may not be
|
|
39
|
+
needed.
|
|
40
|
+
"""
|
|
41
|
+
skill = self._skills.get(name)
|
|
42
|
+
if skill is None:
|
|
43
|
+
return None
|
|
44
|
+
return (
|
|
45
|
+
f'Use the "{skill.name}" skill: call read_skill(name="{skill.name}") '
|
|
46
|
+
"if its instructions are useful and not already in context."
|
|
47
|
+
)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""The plugins that offer skills: to the composer as ``@`` references, and to the model as a list and a tool."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
from zettcode.engine.plugins.plugin import Plugin, PluginSetting
|
|
8
|
+
|
|
9
|
+
from .mentions import SkillMentions
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING: # pragma: no cover - annotations only
|
|
12
|
+
from zett_agent.extensions.base import AgentExtension
|
|
13
|
+
|
|
14
|
+
from zettcode.engine.plugins.context import PluginContext
|
|
15
|
+
from zettcode.engine.plugins.state import AgentBuild
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class SkillResources(Plugin):
|
|
19
|
+
"""The ``@`` resource provider for the skills on this machine.
|
|
20
|
+
|
|
21
|
+
Registering it from a plugin rather than inside the shell keeps the shell generic: it merges whatever providers
|
|
22
|
+
the bundle holds, and the skills are simply one of them.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
name = "skills"
|
|
26
|
+
setting = PluginSetting("skills_enabled", "skills")
|
|
27
|
+
|
|
28
|
+
def activate(self, ctx: PluginContext) -> None:
|
|
29
|
+
"""Offer the discovered skills as ``@`` resources, when skills are on."""
|
|
30
|
+
if ctx.config.skills_enabled:
|
|
31
|
+
ctx.agent.register_mention(SkillMentions(ctx.config.skill_search_roots()))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class SkillTool(Plugin):
|
|
35
|
+
"""The skills the model can load: their list in the prompt and the tool that reads one."""
|
|
36
|
+
|
|
37
|
+
name = "skill-tool"
|
|
38
|
+
description = "Skills the model can load"
|
|
39
|
+
|
|
40
|
+
def activate(self, ctx: PluginContext) -> None:
|
|
41
|
+
"""Hand the agent the skills found under the configured roots, when skills are on."""
|
|
42
|
+
config = ctx.config
|
|
43
|
+
if not config.skills_enabled:
|
|
44
|
+
return
|
|
45
|
+
|
|
46
|
+
def build(_: AgentBuild) -> AgentExtension:
|
|
47
|
+
from zett_agent.extensions.skill import SkillExtension
|
|
48
|
+
|
|
49
|
+
return SkillExtension(config.skill_search_roots())
|
|
50
|
+
|
|
51
|
+
ctx.agent.register_extension_factory("SkillExtension", build)
|
|
File without changes
|