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.
- datalayer_skills-0.2.0/.github/workflows/fix-license-header.yaml +62 -0
- datalayer_skills-0.2.0/.github/workflows/py-tests.yaml +70 -0
- datalayer_skills-0.2.0/.github/workflows/release.yaml +123 -0
- datalayer_skills-0.2.0/.gitignore +128 -0
- datalayer_skills-0.2.0/.licenserc.yaml +23 -0
- datalayer_skills-0.2.0/LICENSE +28 -0
- datalayer_skills-0.2.0/Makefile +42 -0
- datalayer_skills-0.2.0/PKG-INFO +159 -0
- datalayer_skills-0.2.0/README.md +110 -0
- datalayer_skills-0.2.0/datalayer_skills/__init__.py +17 -0
- datalayer_skills-0.2.0/datalayer_skills/__version__.py +5 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/__init__.py +5 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/memory_add/SKILL.md +66 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/memory_add/__init__.py +5 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/memory_add/scripts/add.py +143 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/memory_delete/SKILL.md +79 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/memory_delete/__init__.py +5 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/memory_delete/scripts/delete.py +140 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/memory_delete/scripts/delete_all.py +146 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/memory_list/SKILL.md +66 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/memory_list/__init__.py +5 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/memory_list/scripts/list_memories.py +140 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/memory_search/SKILL.md +66 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/memory_search/__init__.py +5 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/memory_search/scripts/search.py +141 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/whoami/SKILL.md +56 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/whoami/__init__.py +5 -0
- datalayer_skills-0.2.0/datalayer_skills/skills/whoami/scripts/whoami.py +87 -0
- datalayer_skills-0.2.0/pyproject.toml +68 -0
- datalayer_skills-0.2.0/tests/conftest.py +141 -0
- datalayer_skills-0.2.0/tests/test_entrypoints.py +63 -0
- datalayer_skills-0.2.0/tests/test_memory_scripts.py +143 -0
- 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
|
+
[](https://datalayer.ai)
|
|
57
|
+
|
|
58
|
+
[](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).
|