datalayer-skills 0.2.0__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.
Files changed (33) hide show
  1. datalayer_skills-0.2.0/.github/workflows/fix-license-header.yaml +62 -0
  2. datalayer_skills-0.2.0/.github/workflows/py-tests.yaml +70 -0
  3. datalayer_skills-0.2.0/.github/workflows/release.yaml +123 -0
  4. datalayer_skills-0.2.0/.gitignore +128 -0
  5. datalayer_skills-0.2.0/.licenserc.yaml +23 -0
  6. datalayer_skills-0.2.0/LICENSE +28 -0
  7. datalayer_skills-0.2.0/Makefile +42 -0
  8. datalayer_skills-0.2.0/PKG-INFO +159 -0
  9. datalayer_skills-0.2.0/README.md +110 -0
  10. datalayer_skills-0.2.0/datalayer_skills/__init__.py +17 -0
  11. datalayer_skills-0.2.0/datalayer_skills/__version__.py +5 -0
  12. datalayer_skills-0.2.0/datalayer_skills/skills/__init__.py +5 -0
  13. datalayer_skills-0.2.0/datalayer_skills/skills/memory_add/SKILL.md +66 -0
  14. datalayer_skills-0.2.0/datalayer_skills/skills/memory_add/__init__.py +5 -0
  15. datalayer_skills-0.2.0/datalayer_skills/skills/memory_add/scripts/add.py +143 -0
  16. datalayer_skills-0.2.0/datalayer_skills/skills/memory_delete/SKILL.md +79 -0
  17. datalayer_skills-0.2.0/datalayer_skills/skills/memory_delete/__init__.py +5 -0
  18. datalayer_skills-0.2.0/datalayer_skills/skills/memory_delete/scripts/delete.py +140 -0
  19. datalayer_skills-0.2.0/datalayer_skills/skills/memory_delete/scripts/delete_all.py +146 -0
  20. datalayer_skills-0.2.0/datalayer_skills/skills/memory_list/SKILL.md +66 -0
  21. datalayer_skills-0.2.0/datalayer_skills/skills/memory_list/__init__.py +5 -0
  22. datalayer_skills-0.2.0/datalayer_skills/skills/memory_list/scripts/list_memories.py +140 -0
  23. datalayer_skills-0.2.0/datalayer_skills/skills/memory_search/SKILL.md +66 -0
  24. datalayer_skills-0.2.0/datalayer_skills/skills/memory_search/__init__.py +5 -0
  25. datalayer_skills-0.2.0/datalayer_skills/skills/memory_search/scripts/search.py +141 -0
  26. datalayer_skills-0.2.0/datalayer_skills/skills/whoami/SKILL.md +56 -0
  27. datalayer_skills-0.2.0/datalayer_skills/skills/whoami/__init__.py +5 -0
  28. datalayer_skills-0.2.0/datalayer_skills/skills/whoami/scripts/whoami.py +87 -0
  29. datalayer_skills-0.2.0/pyproject.toml +68 -0
  30. datalayer_skills-0.2.0/tests/conftest.py +141 -0
  31. datalayer_skills-0.2.0/tests/test_entrypoints.py +63 -0
  32. datalayer_skills-0.2.0/tests/test_memory_scripts.py +143 -0
  33. datalayer_skills-0.2.0/tests/test_toolset.py +83 -0
@@ -0,0 +1,62 @@
1
+ name: Fix License Headers
2
+
3
+ on:
4
+ pull_request_target:
5
+
6
+ concurrency:
7
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
8
+ cancel-in-progress: true
9
+
10
+ jobs:
11
+ header-license-fix:
12
+ runs-on: ubuntu-latest
13
+
14
+ permissions:
15
+ contents: write
16
+ pull-requests: write
17
+
18
+ steps:
19
+ - name: Checkout
20
+ uses: actions/checkout@v4
21
+ with:
22
+ token: ${{ secrets.GITHUB_TOKEN }}
23
+
24
+ - name: Checkout the branch from the PR that triggered the job
25
+ run: gh pr checkout ${{ github.event.pull_request.number }}
26
+ env:
27
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
28
+
29
+ - name: Fix License Header
30
+ # pin to include https://github.com/apache/skywalking-eyes/pull/168
31
+ uses: apache/skywalking-eyes/header@8e837beb243c264ffcd5ea3abd3d5d8975cd0077
32
+ with:
33
+ mode: fix
34
+
35
+ - name: List files changed
36
+ id: files-changed
37
+ shell: bash -l {0}
38
+ run: |
39
+ set -ex
40
+ export CHANGES=$(git status --porcelain | tee /tmp/modified.log | wc -l)
41
+ cat /tmp/modified.log
42
+
43
+ echo "N_CHANGES=${CHANGES}" >> $GITHUB_OUTPUT
44
+
45
+ git diff
46
+
47
+ - name: Commit any changes
48
+ if: steps.files-changed.outputs.N_CHANGES != '0'
49
+ shell: bash -l {0}
50
+ run: |
51
+ git config user.name "github-actions[bot]"
52
+ git config user.email "github-actions[bot]@users.noreply.github.com"
53
+
54
+ git pull --no-tags
55
+
56
+ git add *
57
+ git commit -m "Automatic application of license header"
58
+
59
+ git config push.default upstream
60
+ git push
61
+ env:
62
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,70 @@
1
+ # Copyright (c) 2023-2026 Datalayer, Inc.
2
+ # Distributed under the terms of the Modified BSD License.
3
+
4
+ name: Py Tests
5
+
6
+ # The package's tests on every supported Python, and ruff. No secrets: the
7
+ # memory skills run against a fake agent runtime on the loopback.
8
+
9
+ on:
10
+ push:
11
+ branches:
12
+ - main
13
+ paths:
14
+ - 'datalayer_skills/**'
15
+ - 'tests/**'
16
+ - 'pyproject.toml'
17
+ - '.github/workflows/py-tests.yaml'
18
+ pull_request:
19
+ branches:
20
+ - main
21
+ paths:
22
+ - 'datalayer_skills/**'
23
+ - 'tests/**'
24
+ - 'pyproject.toml'
25
+ - '.github/workflows/py-tests.yaml'
26
+
27
+ workflow_dispatch:
28
+
29
+ # Called by the Release workflow: a tag publishes nothing until these pass.
30
+ workflow_call:
31
+
32
+ jobs:
33
+ tests:
34
+ runs-on: ubuntu-latest
35
+ strategy:
36
+ matrix:
37
+ python-version: ['3.10', '3.11', '3.12', '3.13']
38
+ steps:
39
+ - name: Checkout
40
+ uses: actions/checkout@v4
41
+
42
+ - uses: astral-sh/setup-uv@v7
43
+ with:
44
+ version: "latest"
45
+ python-version: ${{ matrix.python-version }}
46
+ activate-environment: true
47
+
48
+ - name: Install
49
+ run: uv pip install ".[test]"
50
+
51
+ - name: Run tests
52
+ run: pytest tests/ -q
53
+
54
+ code-style:
55
+ runs-on: ubuntu-latest
56
+ steps:
57
+ - name: Checkout
58
+ uses: actions/checkout@v4
59
+
60
+ - uses: astral-sh/setup-uv@v7
61
+ with:
62
+ version: "latest"
63
+ python-version: '3.12'
64
+ activate-environment: true
65
+
66
+ - name: Ruff
67
+ run: |
68
+ uv pip install ruff
69
+ ruff check .
70
+ ruff format --check .
@@ -0,0 +1,123 @@
1
+ # Copyright (c) 2023-2026 Datalayer, Inc.
2
+ # Distributed under the terms of the Modified BSD License.
3
+
4
+ # Publishes the release a tag names to PyPI (datalayer-skills), with no stored
5
+ # token: PyPI trusts this workflow file (OIDC trusted publishing, through the
6
+ # `pypi` environment). The tag must name the version in
7
+ # datalayer_skills/__version__.py; a version already published is skipped.
8
+ # Nothing is built before the tests (py-tests.yaml, called here) pass on the
9
+ # tagged commit.
10
+
11
+ name: Release
12
+
13
+ on:
14
+ push:
15
+ tags:
16
+ - 'v*'
17
+
18
+ concurrency:
19
+ group: release-${{ github.ref }}
20
+ cancel-in-progress: false
21
+
22
+ permissions:
23
+ contents: read
24
+
25
+ jobs:
26
+ tests:
27
+ uses: ./.github/workflows/py-tests.yaml
28
+
29
+ build:
30
+ needs: tests
31
+ runs-on: ubuntu-latest
32
+ outputs:
33
+ python: ${{ steps.plan.outputs.python }}
34
+ steps:
35
+ - uses: actions/checkout@v4
36
+
37
+ - uses: actions/setup-python@v5
38
+ with:
39
+ python-version: '3.12'
40
+
41
+ - name: Check the tag names the version the package carries
42
+ run: |
43
+ set -euo pipefail
44
+ tag="${GITHUB_REF_NAME#v}"
45
+ version="$(python -c "import re;print(re.search(r'__version__\s*=\s*[\"\']([^\"\']+)', open('datalayer_skills/__version__.py').read())[1])")"
46
+ echo "tag=$tag version=$version"
47
+ test "$tag" = "$version"
48
+
49
+ - name: Find whether it is published yet
50
+ id: plan
51
+ run: |
52
+ set -euo pipefail
53
+ version="${GITHUB_REF_NAME#v}"
54
+ status="$(curl -sL -o /dev/null -w '%{http_code}' "https://pypi.org/pypi/datalayer-skills/$version/json")"
55
+ if [ "$status" = "200" ]; then
56
+ echo "PyPI: datalayer-skills $version is already published, skipping"
57
+ echo "python=" >> "$GITHUB_OUTPUT"
58
+ else
59
+ echo "PyPI: datalayer-skills $version will be published"
60
+ echo "python=yes" >> "$GITHUB_OUTPUT"
61
+ fi
62
+
63
+ - name: Build
64
+ if: steps.plan.outputs.python != ''
65
+ run: |
66
+ set -euo pipefail
67
+ python -m pip install --upgrade pip build
68
+ python -m build --sdist --wheel --outdir dist .
69
+ ls -la dist
70
+
71
+ - name: Check the wheel carries every skill's SKILL.md and scripts
72
+ if: steps.plan.outputs.python != ''
73
+ run: |
74
+ set -euo pipefail
75
+ wheel="$(ls dist/*.whl)"
76
+ listing="$(unzip -l "$wheel")"
77
+ for skill in whoami memory_add memory_search memory_list memory_delete; do
78
+ grep -q "datalayer_skills/skills/$skill/SKILL.md" <<<"$listing"
79
+ grep -q "datalayer_skills/skills/$skill/scripts/" <<<"$listing"
80
+ done
81
+ unzip -p "$wheel" '*.dist-info/entry_points.txt'
82
+
83
+ - uses: actions/upload-artifact@v4
84
+ if: steps.plan.outputs.python != ''
85
+ with:
86
+ name: python
87
+ path: dist/*
88
+
89
+ pypi:
90
+ needs: build
91
+ if: needs.build.outputs.python != ''
92
+ runs-on: ubuntu-latest
93
+ environment: pypi
94
+ permissions:
95
+ id-token: write
96
+ steps:
97
+ - uses: actions/download-artifact@v4
98
+ with:
99
+ name: python
100
+ path: dist
101
+ - uses: pypa/gh-action-pypi-publish@release/v1
102
+ with:
103
+ skip-existing: true
104
+
105
+ release:
106
+ name: GitHub release
107
+ needs: [build, pypi]
108
+ if: always() && needs.build.result == 'success' && needs.pypi.result != 'failure'
109
+ runs-on: ubuntu-latest
110
+ permissions:
111
+ contents: write
112
+ steps:
113
+ - uses: actions/checkout@v4
114
+ with:
115
+ fetch-depth: 0
116
+ - name: Create the release with generated notes
117
+ run: |
118
+ version="${GITHUB_REF_NAME#v}"
119
+ gh release view "$GITHUB_REF_NAME" >/dev/null 2>&1 && exit 0
120
+ gh release create "$GITHUB_REF_NAME" --title "Release $version" --generate-notes \
121
+ --notes "- [PyPI datalayer-skills](https://pypi.org/project/datalayer-skills/$version/)"
122
+ env:
123
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,128 @@
1
+ *.egg-info/
2
+ .ipynb_checkpoints
3
+
4
+ # Created by https://www.gitignore.io/api/python
5
+ # Edit at https://www.gitignore.io/?templates=python
6
+
7
+ ### Python ###
8
+ # Byte-compiled / optimized / DLL files
9
+ __pycache__/
10
+ *.py[cod]
11
+ *$py.class
12
+
13
+ # C extensions
14
+ *.so
15
+
16
+ # Distribution / packaging
17
+ .Python
18
+ build/
19
+ dist/
20
+ downloads/
21
+ lib/
22
+ lib64/
23
+ parts/
24
+ sdist/
25
+ var/
26
+ wheels/
27
+ pip-wheel-metadata/
28
+ share/python-wheels/
29
+ .installed.cfg
30
+
31
+ # PyInstaller
32
+ # Usually these files are written by a python script from a template
33
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
34
+ *.manifest
35
+ *.spec
36
+
37
+ # Installer logs
38
+ pip-log.txt
39
+ pip-delete-this-directory.txt
40
+
41
+ # Unit test / coverage reports
42
+ htmlcov/
43
+ .tox/
44
+ .nox/
45
+ .coverage
46
+ .coverage.*
47
+ .cache
48
+ nosetests.xml
49
+ coverage.xml
50
+ *.cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Environment variables:
59
+ .env
60
+
61
+ # Scrapy stuff:
62
+ .scrapy
63
+
64
+ # Sphinx documentation
65
+ docs/_build/
66
+
67
+ # PyBuilder
68
+ target/
69
+
70
+ # pyenv
71
+ .python-version
72
+
73
+ # celery beat schedule file
74
+ celerybeat-schedule
75
+
76
+ # SageMath parsed files
77
+ *.sage.py
78
+
79
+ # Spyder project settings
80
+ .spyderproject
81
+ .spyproject
82
+
83
+ # Rope project settings
84
+ .ropeproject
85
+
86
+ # Mr Developer
87
+ .mr.developer.cfg
88
+ .project
89
+ .pydevproject
90
+
91
+ # mkdocs documentation
92
+ /site
93
+
94
+ # mypy
95
+ .mypy_cache/
96
+ .dmypy.json
97
+ dmypy.json
98
+
99
+ # ruff
100
+ .ruff_cache
101
+
102
+ # Pyre type checker
103
+ .pyre/
104
+
105
+ # End of https://www.gitignore.io/api/python
106
+
107
+ # OSX files
108
+ .DS_Store
109
+
110
+ # Include
111
+ !**/.*ignore
112
+ !**/.*rc
113
+ !**/.*rc.js
114
+ !**/.*rc.json
115
+ !**/.*rc.yml
116
+ !**/.*config
117
+ !*.*rc.json
118
+ !.github
119
+ !.devcontainer
120
+
121
+ untracked_notebooks/*
122
+ .jupyter_ystore
123
+ .jupyter_ystore.db
124
+ docs/.yarn/*
125
+
126
+ uv.lock
127
+
128
+ generated
@@ -0,0 +1,23 @@
1
+ header:
2
+ license:
3
+ content: |
4
+ Copyright (c) 2025-2026 Datalayer, Inc.
5
+
6
+ BSD 3-Clause License
7
+
8
+
9
+ paths-ignore:
10
+ - '**/*.ipynb'
11
+ - '**/*.json'
12
+ - '**/*.md'
13
+ - '**/*.toml'
14
+ - '**/*.txt'
15
+ - '**/*.yaml'
16
+ - '**/*.yml'
17
+ - '**/.*'
18
+ - '**/__pycache__'
19
+ - 'docs/**/*'
20
+ - 'LICENSE'
21
+ - 'Makefile'
22
+
23
+ comment: on-failure
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2025-2026, Datalayer, Inc.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,42 @@
1
+ # Copyright (c) 2023-2024 Datalayer, Inc.
2
+ #
3
+ # BSD 3-Clause License
4
+
5
+ SHELL=/bin/bash
6
+
7
+ .DEFAULT_GOAL := default
8
+
9
+ .PHONY: clean build test
10
+
11
+ VERSION = "0.0.3"
12
+
13
+ default: all ## Default target is all.
14
+
15
+ help: ## display this help.
16
+ @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
17
+
18
+ all: clean dev ## Clean Install and Build
19
+
20
+ install:
21
+ pip install .
22
+
23
+ dev:
24
+ pip install ".[test,lint,typing]"
25
+
26
+ build:
27
+ pip install build
28
+ python -m build .
29
+
30
+ test: ## Run tests
31
+ python -m pytest tests/ -v
32
+
33
+ clean: ## clean
34
+ git clean -fdx
35
+
36
+ publish-pypi: # publish the pypi package
37
+ git clean -fdx && \
38
+ python -m build
39
+ @exec echo
40
+ @exec echo twine upload ./dist/*-py3-none-any.whl
41
+ @exec echo
42
+ @exec echo https://pypi.org/project/datalayer-skills/#history
@@ -0,0 +1,159 @@
1
+ Metadata-Version: 2.5
2
+ Name: datalayer_skills
3
+ Version: 0.2.0
4
+ Project-URL: Home, https://github.com/datalayer/skills
5
+ Author-email: Datalayer <info@datalayer.io>
6
+ License: BSD 3-Clause License
7
+
8
+ Copyright (c) 2025-2026, Datalayer, Inc.
9
+
10
+ Redistribution and use in source and binary forms, with or without
11
+ modification, are permitted provided that the following conditions are met:
12
+
13
+ 1. Redistributions of source code must retain the above copyright notice, this
14
+ list of conditions and the following disclaimer.
15
+
16
+ 2. Redistributions in binary form must reproduce the above copyright notice,
17
+ this list of conditions and the following disclaimer in the documentation
18
+ and/or other materials provided with the distribution.
19
+
20
+ 3. Neither the name of the copyright holder nor the names of its
21
+ contributors may be used to endorse or promote products derived from
22
+ this software without specific prior written permission.
23
+
24
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ License-File: LICENSE
35
+ Keywords: AI,Agents,Datalayer,Skills
36
+ Classifier: Intended Audience :: Developers
37
+ Classifier: License :: OSI Approved :: BSD License
38
+ Classifier: Programming Language :: Python
39
+ Classifier: Programming Language :: Python :: 3
40
+ Requires-Python: >=3.10
41
+ Requires-Dist: agent-skills
42
+ Requires-Dist: datalayer-core
43
+ Provides-Extra: lint
44
+ Requires-Dist: ruff; extra == 'lint'
45
+ Provides-Extra: test
46
+ Requires-Dist: pytest-asyncio>=0.21; extra == 'test'
47
+ Requires-Dist: pytest>=7.0; extra == 'test'
48
+ Description-Content-Type: text/markdown
49
+
50
+ <!--
51
+ ~ Copyright (c) 2025-2026 Datalayer, Inc.
52
+ ~
53
+ ~ BSD 3-Clause License
54
+ -->
55
+
56
+ [![Datalayer](https://images.datalayer.io/legacy/datalayer-25.svg)](https://datalayer.ai)
57
+
58
+ [![Become a Sponsor](https://img.shields.io/static/v1?label=Become%20a%20Sponsor&message=%E2%9D%A4&logo=GitHub&style=flat&color=1ABC9C)](https://github.com/sponsors/datalayer)
59
+
60
+ # ☰ 🧰 Datalayer Skills
61
+
62
+ Agent skills for the [Datalayer](https://datalayer.ai) platform, discovered by
63
+ [agent-skills](https://github.com/datalayer/agent-skills) through Python entry
64
+ points: install the package, and the skills are there.
65
+
66
+ ## Installation
67
+
68
+ ```bash
69
+ pip install datalayer-skills
70
+ ```
71
+
72
+ The Datalayer agent runtime image installs it, so an agent spec names these
73
+ skills by their names (for example `datalayer-memory-add`) and the runtime
74
+ loads them from the entry points, with no skill spec of their own.
75
+
76
+ ## Available Skills
77
+
78
+ | Skill | Scripts | What it does |
79
+ |-------|---------|--------------|
80
+ | `datalayer-whoami` | `whoami` | The authenticated user's profile from Datalayer IAM |
81
+ | `datalayer-memory-add` | `add` | Keep one thing in the person's memory of the agent, in their words |
82
+ | `datalayer-memory-search` | `search` | The memories closest to a query |
83
+ | `datalayer-memory-list` | `list_memories` | Every memory, newest first, with its id |
84
+ | `datalayer-memory-delete` | `delete`, `delete_all` | Forget one memory by id, or everything once the person confirmed how many |
85
+
86
+ ## The memory skills
87
+
88
+ An agent whose spec says `memory: mem0` keeps a durable memory of the person
89
+ whose runtime it is: mem0, in PostgreSQL (pgvector) on a Datalayer runtime,
90
+ embedded through ai-inference with the runtime's token. The memory skills let
91
+ the person keep, read, list and delete it on request.
92
+
93
+ **How the scripts reach the memory.** A skill script runs in the agent's
94
+ sandbox, the Jupyter container beside the agent runtime in the same pod. It
95
+ calls the runtime's memory routes on the pod's loopback (by default
96
+ `http://127.0.0.1:8765`), with the Python standard library only:
97
+
98
+ | Script | Route |
99
+ |--------|-------|
100
+ | `add` | `POST /api/v1/agents/{agent}/memory` with `{"content", "metadata"}` |
101
+ | `search` | `POST /api/v1/agents/{agent}/memory/search` with `{"query"}` |
102
+ | `list_memories` | `GET /api/v1/agents/{agent}/memory` |
103
+ | `delete` | `DELETE /api/v1/agents/{agent}/memory/{id}` |
104
+ | `delete_all` | `DELETE /api/v1/agents/{agent}/memory?count=N` |
105
+
106
+ The scripts do not use mem0's client directly. That would need the PostgreSQL
107
+ password and the ai-inference token in the sandbox, which holds neither, and
108
+ it would let the script choose whose memory it opens. Going through the
109
+ runtime needs no egress (the call stays in the pod) and no secret, and keeps
110
+ the scope where agent-runtimes keeps it.
111
+
112
+ **Scope.** The runtime keeps the memory under the composite key (user, agent):
113
+ the user is the runtime owner's personal account, read from the runtime's
114
+ trusted environment (`DATALAYER_USER_UID`), and the agent is the agent's own
115
+ id. The scripts send neither. An id that is not one of this agent's memories
116
+ of the person is not found, and `delete_all` forgets nothing when the agent
117
+ remembers more than the `count` the person confirmed.
118
+
119
+ **Which agent.** `--agent` (the agent's name on the runtime), else
120
+ `AGENT_RUNTIMES_AGENT_ID`, else the runtime's only agent. When several agents
121
+ run on the runtime, the script asks for `--agent`.
122
+
123
+ **Optional environment.** `AGENT_RUNTIMES_URL` (another runtime),
124
+ `AGENT_RUNTIMES_PORT` (its port on the loopback).
125
+
126
+ ## How It Works
127
+
128
+ The package declares each skill in the `agent_skills.skills` entry-point group
129
+ of `pyproject.toml`:
130
+
131
+ ```toml
132
+ [project.entry-points."agent_skills.skills"]
133
+ datalayer-whoami = "datalayer_skills.skills.whoami"
134
+ datalayer-memory-add = "datalayer_skills.skills.memory_add"
135
+ datalayer-memory-search = "datalayer_skills.skills.memory_search"
136
+ datalayer-memory-list = "datalayer_skills.skills.memory_list"
137
+ datalayer-memory-delete = "datalayer_skills.skills.memory_delete"
138
+ ```
139
+
140
+ Each value is a module that holds a `SKILL.md` and a `scripts/` directory.
141
+ `agent_skills.discover_entrypoint_skills()` loads them, and
142
+ `AgentSkillsToolset(discover_entrypoints=True)` offers them to an agent.
143
+ An agent runtime loads the ones its agent spec names.
144
+
145
+ ## Development
146
+
147
+ ```bash
148
+ pip install -e ".[test]"
149
+ pytest
150
+ ```
151
+
152
+ The tests run each memory script against a fake agent runtime on the
153
+ loopback, and through agent-skills' toolset with an eval sandbox.
154
+
155
+ ## Release
156
+
157
+ Set the version in `datalayer_skills/__version__.py`, merge to `main`, then
158
+ push the tag `v<version>`. The Release workflow runs the tests, builds, and
159
+ publishes to PyPI through trusted publishing (the `pypi` environment).