chore: import upstream snapshot with attribution
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:20:55 +08:00
commit d25d482dc2
13754 changed files with 4996608 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
import type { RedisCommandParams, RedisCommandResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisCommandTool: ToolConfig<RedisCommandParams, RedisCommandResponse> = {
id: 'redis_command',
name: 'Redis Command',
description:
'Execute a raw Redis command as a JSON array (e.g. ["HSET", "key", "field", "value"]).',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
command: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Redis command as a JSON array (e.g. ["SET", "key", "value"])',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => {
let parsed: unknown
try {
parsed = JSON.parse(params.command)
} catch {
throw new Error(
`Invalid JSON in command: ${params.command}. Expected a JSON array like ["SET", "key", "value"].`
)
}
const [cmd, ...args] = Array.isArray(parsed) ? parsed : [parsed]
return {
url: params.url,
command: String(cmd),
args: args.map(String),
}
},
},
transformResponse: async (response: Response, params?: RedisCommandParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to execute Redis command')
}
return {
success: true,
output: {
command: params?.command ?? '',
result: data.result ?? null,
},
}
},
outputs: {
command: { type: 'string', description: 'The command that was executed' },
result: { type: 'json', description: 'The result of the command' },
},
}
+59
View File
@@ -0,0 +1,59 @@
import type { RedisDeleteParams, RedisDeleteResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisDeleteTool: ToolConfig<RedisDeleteParams, RedisDeleteResponse> = {
id: 'redis_delete',
name: 'Redis Delete',
description: 'Delete a key from Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The key to delete',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'DEL',
args: [params.key],
}),
},
transformResponse: async (response: Response, params?: RedisDeleteParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to delete key from Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
deletedCount: data.result ?? 0,
},
}
},
outputs: {
key: { type: 'string', description: 'The key that was deleted' },
deletedCount: {
type: 'number',
description: 'Number of keys deleted (0 if key did not exist, 1 if deleted)',
},
},
}
+56
View File
@@ -0,0 +1,56 @@
import type { RedisExistsParams, RedisExistsResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisExistsTool: ToolConfig<RedisExistsParams, RedisExistsResponse> = {
id: 'redis_exists',
name: 'Redis EXISTS',
description: 'Check if a key exists in Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The key to check',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'EXISTS',
args: [params.key],
}),
},
transformResponse: async (response: Response, params?: RedisExistsParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to check key existence in Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
exists: data.result === 1,
},
}
},
outputs: {
key: { type: 'string', description: 'The key that was checked' },
exists: { type: 'boolean', description: 'Whether the key exists (true) or not (false)' },
},
}
+65
View File
@@ -0,0 +1,65 @@
import type { RedisExpireParams, RedisExpireResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisExpireTool: ToolConfig<RedisExpireParams, RedisExpireResponse> = {
id: 'redis_expire',
name: 'Redis EXPIRE',
description: 'Set an expiration time (in seconds) on a key in Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The key to set expiration on',
},
seconds: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Timeout in seconds',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'EXPIRE',
args: [params.key, params.seconds],
}),
},
transformResponse: async (response: Response, params?: RedisExpireParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to set expiration in Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
result: data.result ?? 0,
},
}
},
outputs: {
key: { type: 'string', description: 'The key that expiration was set on' },
result: {
type: 'number',
description: '1 if the timeout was set, 0 if the key does not exist',
},
},
}
+60
View File
@@ -0,0 +1,60 @@
import type { RedisGetParams, RedisGetResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisGetTool: ToolConfig<RedisGetParams, RedisGetResponse> = {
id: 'redis_get',
name: 'Redis Get',
description: 'Get the value of a key from Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The key to retrieve',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'GET',
args: [params.key],
}),
},
transformResponse: async (response: Response, params?: RedisGetParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to get key from Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
value: data.result ?? null,
},
}
},
outputs: {
key: { type: 'string', description: 'The key that was retrieved' },
value: {
type: 'string',
description: 'The value of the key, or null if the key does not exist',
optional: true,
},
},
}
+67
View File
@@ -0,0 +1,67 @@
import type { RedisHDelParams, RedisHDelResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisHDelTool: ToolConfig<RedisHDelParams, RedisHDelResponse> = {
id: 'redis_hdel',
name: 'Redis HDEL',
description: 'Delete a field from a hash stored at a key in Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The hash key',
},
field: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The field name to delete',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'HDEL',
args: [params.key, params.field],
}),
},
transformResponse: async (response: Response, params?: RedisHDelParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to delete hash field from Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
field: params?.field ?? '',
deleted: data.result ?? 0,
},
}
},
outputs: {
key: { type: 'string', description: 'The hash key' },
field: { type: 'string', description: 'The field that was deleted' },
deleted: {
type: 'number',
description: 'Number of fields removed (1 if deleted, 0 if field did not exist)',
},
},
}
+68
View File
@@ -0,0 +1,68 @@
import type { RedisHGetParams, RedisHGetResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisHGetTool: ToolConfig<RedisHGetParams, RedisHGetResponse> = {
id: 'redis_hget',
name: 'Redis HGET',
description: 'Get the value of a field in a hash stored at a key in Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The hash key',
},
field: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The field name to retrieve',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'HGET',
args: [params.key, params.field],
}),
},
transformResponse: async (response: Response, params?: RedisHGetParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to get hash field from Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
field: params?.field ?? '',
value: data.result ?? null,
},
}
},
outputs: {
key: { type: 'string', description: 'The hash key' },
field: { type: 'string', description: 'The field that was retrieved' },
value: {
type: 'string',
description: 'The field value, or null if the field or key does not exist',
optional: true,
},
},
}
+75
View File
@@ -0,0 +1,75 @@
import type { RedisHGetAllParams, RedisHGetAllResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisHGetAllTool: ToolConfig<RedisHGetAllParams, RedisHGetAllResponse> = {
id: 'redis_hgetall',
name: 'Redis HGETALL',
description: 'Get all fields and values of a hash stored at a key in Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The hash key',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'HGETALL',
args: [params.key],
}),
},
transformResponse: async (response: Response, params?: RedisHGetAllParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to get hash from Redis')
}
// ioredis .call() returns HGETALL as a flat array [field1, value1, field2, value2, ...]
// We convert it to a key-value object for usability
const raw = data.result
let fields: Record<string, string> = {}
if (Array.isArray(raw)) {
for (let i = 0; i < raw.length; i += 2) {
fields[raw[i]] = raw[i + 1] ?? ''
}
} else if (raw && typeof raw === 'object') {
fields = raw
}
return {
success: true,
output: {
key: params?.key ?? '',
fields,
fieldCount: Object.keys(fields).length,
},
}
},
outputs: {
key: { type: 'string', description: 'The hash key' },
fields: {
type: 'object',
description:
'All field-value pairs in the hash as a key-value object. Empty object if the key does not exist.',
},
fieldCount: { type: 'number', description: 'Number of fields in the hash' },
},
}
+73
View File
@@ -0,0 +1,73 @@
import type { RedisHSetParams, RedisHSetResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisHSetTool: ToolConfig<RedisHSetParams, RedisHSetResponse> = {
id: 'redis_hset',
name: 'Redis HSET',
description: 'Set a field in a hash stored at a key in Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The hash key',
},
field: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The field name within the hash',
},
value: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The value to set for the field',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'HSET',
args: [params.key, params.field, params.value],
}),
},
transformResponse: async (response: Response, params?: RedisHSetParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to set hash field in Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
field: params?.field ?? '',
result: data.result ?? 0,
},
}
},
outputs: {
key: { type: 'string', description: 'The hash key' },
field: { type: 'string', description: 'The field that was set' },
result: {
type: 'number',
description: 'Number of fields added (1 if new, 0 if updated)',
},
},
}
+56
View File
@@ -0,0 +1,56 @@
import type { RedisIncrParams, RedisIncrResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisIncrTool: ToolConfig<RedisIncrParams, RedisIncrResponse> = {
id: 'redis_incr',
name: 'Redis INCR',
description: 'Increment the integer value of a key by one in Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The key to increment',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'INCR',
args: [params.key],
}),
},
transformResponse: async (response: Response, params?: RedisIncrParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to increment key in Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
value: data.result ?? 0,
},
}
},
outputs: {
key: { type: 'string', description: 'The key that was incremented' },
value: { type: 'number', description: 'The new value after increment' },
},
}
+62
View File
@@ -0,0 +1,62 @@
import type { RedisIncrbyParams, RedisIncrbyResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisIncrbyTool: ToolConfig<RedisIncrbyParams, RedisIncrbyResponse> = {
id: 'redis_incrby',
name: 'Redis INCRBY',
description: 'Increment the integer value of a key by a given amount in Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The key to increment',
},
increment: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Amount to increment by (negative to decrement)',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'INCRBY',
args: [params.key, params.increment],
}),
},
transformResponse: async (response: Response, params?: RedisIncrbyParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to increment key in Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
value: data.result ?? 0,
},
}
},
outputs: {
key: { type: 'string', description: 'The key that was incremented' },
value: { type: 'number', description: 'The new value after increment' },
},
}
+22
View File
@@ -0,0 +1,22 @@
export { redisCommandTool } from '@/tools/redis/command'
export { redisDeleteTool } from '@/tools/redis/delete'
export { redisExistsTool } from '@/tools/redis/exists'
export { redisExpireTool } from '@/tools/redis/expire'
export { redisGetTool } from '@/tools/redis/get'
export { redisHDelTool } from '@/tools/redis/hdel'
export { redisHGetTool } from '@/tools/redis/hget'
export { redisHGetAllTool } from '@/tools/redis/hgetall'
export { redisHSetTool } from '@/tools/redis/hset'
export { redisIncrTool } from '@/tools/redis/incr'
export { redisIncrbyTool } from '@/tools/redis/incrby'
export { redisKeysTool } from '@/tools/redis/keys'
export { redisLLenTool } from '@/tools/redis/llen'
export { redisLPopTool } from '@/tools/redis/lpop'
export { redisLPushTool } from '@/tools/redis/lpush'
export { redisLRangeTool } from '@/tools/redis/lrange'
export { redisPersistTool } from '@/tools/redis/persist'
export { redisRPopTool } from '@/tools/redis/rpop'
export { redisRPushTool } from '@/tools/redis/rpush'
export { redisSetTool } from '@/tools/redis/set'
export { redisSetnxTool } from '@/tools/redis/setnx'
export { redisTtlTool } from '@/tools/redis/ttl'
+65
View File
@@ -0,0 +1,65 @@
import type { RedisKeysParams, RedisKeysResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisKeysTool: ToolConfig<RedisKeysParams, RedisKeysResponse> = {
id: 'redis_keys',
name: 'Redis Keys',
description:
'List all keys matching a pattern in Redis. Avoid using on large databases in production; use the Redis Command tool with SCAN for large key spaces.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
pattern: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pattern to match keys (default: * for all keys)',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'KEYS',
args: [params.pattern || '*'],
}),
},
transformResponse: async (response: Response, params?: RedisKeysParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to list keys from Redis')
}
const keys = data.result ?? []
return {
success: true,
output: {
pattern: params?.pattern || '*',
keys,
count: keys.length,
},
}
},
outputs: {
pattern: { type: 'string', description: 'The pattern used to match keys' },
keys: {
type: 'array',
description: 'List of keys matching the pattern',
items: { type: 'string', description: 'A Redis key' },
},
count: { type: 'number', description: 'Number of keys found' },
},
}
+59
View File
@@ -0,0 +1,59 @@
import type { RedisLLenParams, RedisLLenResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisLLenTool: ToolConfig<RedisLLenParams, RedisLLenResponse> = {
id: 'redis_llen',
name: 'Redis LLEN',
description: 'Get the length of a list stored at a key in Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The list key',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'LLEN',
args: [params.key],
}),
},
transformResponse: async (response: Response, params?: RedisLLenParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to get list length from Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
length: data.result ?? 0,
},
}
},
outputs: {
key: { type: 'string', description: 'The list key' },
length: {
type: 'number',
description: 'The length of the list, or 0 if the key does not exist',
},
},
}
+60
View File
@@ -0,0 +1,60 @@
import type { RedisLPopParams, RedisLPopResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisLPopTool: ToolConfig<RedisLPopParams, RedisLPopResponse> = {
id: 'redis_lpop',
name: 'Redis LPOP',
description: 'Remove and return the first element of a list stored at a key in Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The list key',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'LPOP',
args: [params.key],
}),
},
transformResponse: async (response: Response, params?: RedisLPopParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to pop from list in Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
value: data.result ?? null,
},
}
},
outputs: {
key: { type: 'string', description: 'The list key' },
value: {
type: 'string',
description: 'The removed element, or null if the list is empty',
optional: true,
},
},
}
+62
View File
@@ -0,0 +1,62 @@
import type { RedisLPushParams, RedisLPushResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisLPushTool: ToolConfig<RedisLPushParams, RedisLPushResponse> = {
id: 'redis_lpush',
name: 'Redis LPUSH',
description: 'Prepend a value to a list stored at a key in Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The list key',
},
value: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The value to prepend',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'LPUSH',
args: [params.key, params.value],
}),
},
transformResponse: async (response: Response, params?: RedisLPushParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to push to list in Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
length: data.result ?? 0,
},
}
},
outputs: {
key: { type: 'string', description: 'The list key' },
length: { type: 'number', description: 'Length of the list after the push' },
},
}
+76
View File
@@ -0,0 +1,76 @@
import type { RedisLRangeParams, RedisLRangeResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisLRangeTool: ToolConfig<RedisLRangeParams, RedisLRangeResponse> = {
id: 'redis_lrange',
name: 'Redis LRANGE',
description: 'Get a range of elements from a list stored at a key in Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The list key',
},
start: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Start index (0-based)',
},
stop: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Stop index (-1 for all elements)',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'LRANGE',
args: [params.key, params.start, params.stop],
}),
},
transformResponse: async (response: Response, params?: RedisLRangeParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to get list range from Redis')
}
const values = data.result ?? []
return {
success: true,
output: {
key: params?.key ?? '',
values,
count: values.length,
},
}
},
outputs: {
key: { type: 'string', description: 'The list key' },
values: {
type: 'array',
description: 'List elements in the specified range',
items: { type: 'string', description: 'A list element' },
},
count: { type: 'number', description: 'Number of elements returned' },
},
}
+60
View File
@@ -0,0 +1,60 @@
import type { RedisPersistParams, RedisPersistResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisPersistTool: ToolConfig<RedisPersistParams, RedisPersistResponse> = {
id: 'redis_persist',
name: 'Redis PERSIST',
description: 'Remove the expiration from a key in Redis, making it persist indefinitely.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The key to persist',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'PERSIST',
args: [params.key],
}),
},
transformResponse: async (response: Response, params?: RedisPersistParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to persist key in Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
result: data.result ?? 0,
},
}
},
outputs: {
key: { type: 'string', description: 'The key that was persisted' },
result: {
type: 'number',
description:
'1 if the expiration was removed, 0 if the key does not exist or has no expiration',
},
},
}
+60
View File
@@ -0,0 +1,60 @@
import type { RedisRPopParams, RedisRPopResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisRPopTool: ToolConfig<RedisRPopParams, RedisRPopResponse> = {
id: 'redis_rpop',
name: 'Redis RPOP',
description: 'Remove and return the last element of a list stored at a key in Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The list key',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'RPOP',
args: [params.key],
}),
},
transformResponse: async (response: Response, params?: RedisRPopParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to pop from list in Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
value: data.result ?? null,
},
}
},
outputs: {
key: { type: 'string', description: 'The list key' },
value: {
type: 'string',
description: 'The removed element, or null if the list is empty',
optional: true,
},
},
}
+62
View File
@@ -0,0 +1,62 @@
import type { RedisRPushParams, RedisRPushResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisRPushTool: ToolConfig<RedisRPushParams, RedisRPushResponse> = {
id: 'redis_rpush',
name: 'Redis RPUSH',
description: 'Append a value to the end of a list stored at a key in Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The list key',
},
value: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The value to append',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'RPUSH',
args: [params.key, params.value],
}),
},
transformResponse: async (response: Response, params?: RedisRPushParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to push to list in Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
length: data.result ?? 0,
},
}
},
outputs: {
key: { type: 'string', description: 'The list key' },
length: { type: 'number', description: 'Length of the list after the push' },
},
}
+68
View File
@@ -0,0 +1,68 @@
import type { RedisSetParams, RedisSetResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisSetTool: ToolConfig<RedisSetParams, RedisSetResponse> = {
id: 'redis_set',
name: 'Redis Set',
description: 'Set the value of a key in Redis with an optional expiration time in seconds.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The key to set',
},
value: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The value to store',
},
ex: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Expiration time in seconds (optional)',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'SET',
args: params.ex ? [params.key, params.value, 'EX', params.ex] : [params.key, params.value],
}),
},
transformResponse: async (response: Response, params?: RedisSetParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to set key in Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
result: data.result ?? 'OK',
},
}
},
outputs: {
key: { type: 'string', description: 'The key that was set' },
result: { type: 'string', description: 'The result of the SET operation (typically "OK")' },
},
}
+65
View File
@@ -0,0 +1,65 @@
import type { RedisSetnxParams, RedisSetnxResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisSetnxTool: ToolConfig<RedisSetnxParams, RedisSetnxResponse> = {
id: 'redis_setnx',
name: 'Redis SETNX',
description: 'Set the value of a key in Redis only if the key does not already exist.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The key to set',
},
value: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The value to store',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'SETNX',
args: [params.key, params.value],
}),
},
transformResponse: async (response: Response, params?: RedisSetnxParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to set key in Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
wasSet: data.result === 1,
},
}
},
outputs: {
key: { type: 'string', description: 'The key that was set' },
wasSet: {
type: 'boolean',
description: 'Whether the key was set (true) or already existed (false)',
},
},
}
+60
View File
@@ -0,0 +1,60 @@
import type { RedisTtlParams, RedisTtlResponse } from '@/tools/redis/types'
import type { ToolConfig } from '@/tools/types'
export const redisTtlTool: ToolConfig<RedisTtlParams, RedisTtlResponse> = {
id: 'redis_ttl',
name: 'Redis TTL',
description: 'Get the remaining time to live (in seconds) of a key in Redis.',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Redis connection URL (e.g. redis://user:password@host:port)',
},
key: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The key to check TTL for',
},
},
request: {
url: '/api/tools/redis/execute',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
url: params.url,
command: 'TTL',
args: [params.key],
}),
},
transformResponse: async (response: Response, params?: RedisTtlParams) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to get TTL from Redis')
}
return {
success: true,
output: {
key: params?.key ?? '',
ttl: data.result ?? -2,
},
}
},
outputs: {
key: { type: 'string', description: 'The key that was checked' },
ttl: {
type: 'number',
description:
'Remaining TTL in seconds. Positive integer if TTL set, -1 if no expiration, -2 if key does not exist.',
},
},
}
+266
View File
@@ -0,0 +1,266 @@
import type { ToolResponse } from '@/tools/types'
interface RedisBaseParams {
url: string
}
export interface RedisGetParams extends RedisBaseParams {
key: string
}
export interface RedisSetParams extends RedisBaseParams {
key: string
value: string
ex?: number
}
export interface RedisDeleteParams extends RedisBaseParams {
key: string
}
export interface RedisKeysParams extends RedisBaseParams {
pattern?: string
}
export interface RedisCommandParams extends RedisBaseParams {
command: string
}
export interface RedisHSetParams extends RedisBaseParams {
key: string
field: string
value: string
}
export interface RedisHGetParams extends RedisBaseParams {
key: string
field: string
}
export interface RedisHGetAllParams extends RedisBaseParams {
key: string
}
export interface RedisIncrParams extends RedisBaseParams {
key: string
}
export interface RedisIncrbyParams extends RedisBaseParams {
key: string
increment: number
}
export interface RedisExistsParams extends RedisBaseParams {
key: string
}
export interface RedisSetnxParams extends RedisBaseParams {
key: string
value: string
}
export interface RedisExpireParams extends RedisBaseParams {
key: string
seconds: number
}
export interface RedisTtlParams extends RedisBaseParams {
key: string
}
export interface RedisLPushParams extends RedisBaseParams {
key: string
value: string
}
export interface RedisLRangeParams extends RedisBaseParams {
key: string
start: number
stop: number
}
export interface RedisRPushParams extends RedisBaseParams {
key: string
value: string
}
export interface RedisLPopParams extends RedisBaseParams {
key: string
}
export interface RedisRPopParams extends RedisBaseParams {
key: string
}
export interface RedisLLenParams extends RedisBaseParams {
key: string
}
export interface RedisHDelParams extends RedisBaseParams {
key: string
field: string
}
export interface RedisPersistParams extends RedisBaseParams {
key: string
}
export interface RedisGetResponse extends ToolResponse {
output: {
key: string
value: string | null
}
}
export interface RedisSetResponse extends ToolResponse {
output: {
key: string
result: string
}
}
export interface RedisDeleteResponse extends ToolResponse {
output: {
key: string
deletedCount: number
}
}
export interface RedisKeysResponse extends ToolResponse {
output: {
pattern: string
keys: string[]
count: number
}
}
export interface RedisCommandResponse extends ToolResponse {
output: {
command: string
result: unknown
}
}
export interface RedisHSetResponse extends ToolResponse {
output: {
key: string
field: string
result: number
}
}
export interface RedisHGetResponse extends ToolResponse {
output: {
key: string
field: string
value: string | null
}
}
export interface RedisHGetAllResponse extends ToolResponse {
output: {
key: string
fields: Record<string, string>
fieldCount: number
}
}
export interface RedisIncrResponse extends ToolResponse {
output: {
key: string
value: number
}
}
export interface RedisIncrbyResponse extends ToolResponse {
output: {
key: string
value: number
}
}
export interface RedisExistsResponse extends ToolResponse {
output: {
key: string
exists: boolean
}
}
export interface RedisSetnxResponse extends ToolResponse {
output: {
key: string
wasSet: boolean
}
}
export interface RedisExpireResponse extends ToolResponse {
output: {
key: string
result: number
}
}
export interface RedisTtlResponse extends ToolResponse {
output: {
key: string
ttl: number
}
}
export interface RedisLPushResponse extends ToolResponse {
output: {
key: string
length: number
}
}
export interface RedisLRangeResponse extends ToolResponse {
output: {
key: string
values: string[]
count: number
}
}
export interface RedisRPushResponse extends ToolResponse {
output: {
key: string
length: number
}
}
export interface RedisLPopResponse extends ToolResponse {
output: {
key: string
value: string | null
}
}
export interface RedisRPopResponse extends ToolResponse {
output: {
key: string
value: string | null
}
}
export interface RedisLLenResponse extends ToolResponse {
output: {
key: string
length: number
}
}
export interface RedisHDelResponse extends ToolResponse {
output: {
key: string
field: string
deleted: number
}
}
export interface RedisPersistResponse extends ToolResponse {
output: {
key: string
result: number
}
}