blob: 548d6fb72a8cc38ad9bc81c6de2d564760e4cc7b [file] [view]
Implement the tools as separate tools in folder tools/
Rule: an action is stored folder `packages/<package>/<name>`, functions is a synonym for action.
Rule: assume the packages referenced by the tools are already available and preinstalled.
Rule: `action-add-secret`, `action-add-s3`, `action-add-redis`, `action-add-postgresql`, and `action-add-milvus` are idempotent if the secret or service is already present in `__main__.py`, skip the injection silently and return a message saying it is already configured.
Implement the following tools in folder tools/ using this template:
```
import { tool } from "@opencode-ai/plugin"
export default tool({
description: "<description>",
args: {
<arg>: tool.schema.<type>().describe("<arg description>"),
},
async execute(args) {
<tool logic>
return `<results>`
},
})
```
Generate each tools as standalone scripts, avoid separate helpers files, duplicate code if needed.
# tool action-new
This tool creates a new action public (API endpoint) or private (typically for initializations).
## parameters
Receive an <endpoint> (`name` or `package/name`, defaults to `v1` package) and an optional <public> flag (defaults to `true`). Set `public: false` to create a private action (used for initialization tasks in the `init` package).
- ensure package and name only contain letters, numbers and '-' and start with a letter
- <module> is the name with '-' replaced with '_' (example: 'new-user' becomes 'new_user')
## generation
- create a folder `packages/<package>/<name>`
- write a file `packages/<package>/<name>/__main__.py` with the content (where `<public>` is `true` or `false`):
```
#--kind python:default
#--web <public>
# Note: this timeout is 5 minutes - 10 minutes is max allowed
#--timeout 300000
import types, os, <module>
builder = []
## build-context ##
def main(args):
try:
ctx = types.SimpleNamespace()
for fn in builder: fn(args, ctx)
return { "body": <module>.main(args, ctx=ctx) }
except Exception as e:
import traceback
traceback.print_exc()
return {
"body": {"error": str(e) },
"statusCode": 500
}
```
- write a file `packages/<package>/<name>/<module>.py` with the content:
```
def main(args, ctx=None):
inp = args.get("input", "<module>")
out = inp
return out
```
## returns
The resulting `<package>/<name>`.
# tool action-invoke
This tool invokes an api action.
## parameters
Receive an <endpoint> (`package/action`) and a series of key=value pairs.
## executes
the command `ops action invoke <endpoint> -p "<key1>" "<value1>" ... -p "<keyn>" "<valuen>"`
## returns
the json output of the command
# tool action-add-secret
## parameters
Receive an <endpoint> (`name` or `package/name`) and a <secret> name.
## generation
This tool adds a new secret <MY_SECRET> to an endpoint/action/function.
First checks the secret is available in `.env`. If not, warn the user and suggest to add it to the environment.
- adds in `__main__.py` after "## build-context ##":
```
#--param <MY_SECRET> "$<MY_SECRET>"
builder.append(lambda args, ctx: setattr(ctx, '<MY_SECRET>', args.get("<MY_SECRET>", os.getenv("<MY_SECRET>"))))
```
## returns
Information on the updated context.
# tool action-add-s3
## parameters
Receive an <endpoint> (`name` or `package/name`).
## generation
This tool adds S3 to the context of an endpoint/action/function, making available:
- `ctx.S3_CLIENT` the S3 client
- `ctx.S3_DATA` the S3 data bucket (private)
- `ctx.S3_WEB` the S3 web bucket (public)
- `ctx.S3_PUBLIC` the public URL to access S3
- adds in `__main__.py` after "## build-context ##":
```
#--param S3_HOST "$S3_HOST"
#--param S3_PORT "$S3_PORT"
#--param S3_ACCESS_KEY "$S3_ACCESS_KEY"
#--param S3_SECRET_KEY "$S3_SECRET_KEY"
#--param S3_BUCKET_DATA "$S3_BUCKET_DATA"
#--param S3_BUCKET_STATIC "$S3_BUCKET_STATIC"
#--param S3_PUBLIC "$OPSDEV_S3"
import boto3
from botocore.client import Config
def init_s3(args, ctx):
host = args.get("S3_HOST", os.getenv("S3_HOST"))
port = args.get("S3_PORT", os.getenv("S3_PORT"))
url = f"http://{host}:{port}"
key = args.get("S3_ACCESS_KEY", os.getenv("S3_ACCESS_KEY"))
sec = args.get("S3_SECRET_KEY", os.getenv("S3_SECRET_KEY"))
cfg = Config(signature_version='s3v4')
ctx.S3_CLIENT = boto3.client('s3', region_name='us-east-1', endpoint_url=url, aws_access_key_id=key, aws_secret_access_key=sec, config=cfg)
ctx.S3_DATA = args.get("S3_BUCKET_DATA", os.getenv("S3_BUCKET_DATA"))
ctx.S3_WEB = args.get("S3_BUCKET_STATIC", os.getenv("S3_BUCKET_STATIC"))
ctx.S3_PUBLIC = args.get("S3_PUBLIC", os.getenv("OPSDEV_S3"))
builder.append(init_s3)
```
## returns
Information on the updated context.
# tool action-add-redis
## parameters
Receive an <endpoint> (`name` or `package/name`).
## generation
This tool adds a Redis connection to an endpoint/action/function, making available:
- `ctx.REDIS` the Redis client
- `ctx.REDIS_PREFIX` the key prefix
- adds in `__main__.py` after "## build-context ##":
```
#--param REDIS_URL "$REDIS_URL"
#--param REDIS_PREFIX "$REDIS_PREFIX"
import redis
def init_redis(args, ctx):
ctx.REDIS = redis.from_url(args.get("REDIS_URL", os.getenv("REDIS_URL")))
ctx.REDIS_PREFIX = args.get("REDIS_PREFIX", os.getenv("REDIS_PREFIX"))
builder.append(init_redis)
```
## returns
Information on the updated context.
# tool action-add-postgresql
## parameters
Receive an <endpoint> (`name` or `package/name`).
## generation
This tool adds a PostgreSQL connection to an endpoint/action/function, making available:
- `ctx.POSTGRESQL` the psycopg connection
- adds in `__main__.py` after "## build-context ##":
```
#--param POSTGRES_URL "$POSTGRES_URL"
import psycopg
def init_postgresql(args, ctx):
dburl = args.get("POSTGRES_URL", os.getenv("POSTGRES_URL"))
ctx.POSTGRESQL = psycopg.connect(dburl)
builder.append(init_postgresql)
```
## returns
Information on the updated context.
# tool action-add-milvus
## parameters
Receive an <endpoint> (`name` or `package/name`).
## generation
This tool adds a Milvus vector DB connection to an endpoint/action/function, making available:
- `ctx.MILVUS` the MilvusClient instance
- adds in `__main__.py` after "## build-context ##":
```
#--param MILVUS_HOST "$MILVUS_HOST"
#--param MILVUS_PORT "$MILVUS_PORT"
#--param MILVUS_DB_NAME "$MILVUS_DB_NAME"
#--param MILVUS_TOKEN "$MILVUS_TOKEN"
from pymilvus import MilvusClient
def init_milvus(args, ctx):
host = args.get('MILVUS_HOST', os.getenv('MILVUS_HOST'))
port = args.get('MILVUS_PORT', os.getenv('MILVUS_PORT'))
uri = f"http://{host}:{port}"
token = args.get("MILVUS_TOKEN", os.getenv("MILVUS_TOKEN"))
db_name = args.get("MILVUS_DB_NAME", os.getenv("MILVUS_DB_NAME"))
ctx.MILVUS = MilvusClient(uri=uri, token=token, db_name=db_name)
builder.append(init_milvus)
```
## returns
Information on the updated context.
# tool action-requirements
## parameters
Receive an <endpoint> (`name` or `package/name`) and a <library> name.
## generation
The tool will do nothing when one of the following libraries is required (use the available version), otherwise will add the library to the file
packages/<package>/<name>/requirements.txt
- requests
- ollama
- openai
- pymilvus
- redis
- pyyaml
- boto3
- psycopg
- beautifulsoup4
- pillow
- nltk
- httplib2
- kafka_python
- python-dateutil
- scrapy
- simplejson
- twisted
- netifaces
- pymongo
- minio
- langdetect
- plotly
- joblib
- lightgbm
- feedparser
- numpy
- scikit-learn
- langchain
- langchain-ollama
- langchain-openai
- bcrypt