chore: import upstream snapshot with attribution
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
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
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
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
import type { Neo4jCreateParams, Neo4jResponse } from '@/tools/neo4j/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const createTool: ToolConfig<Neo4jCreateParams, Neo4jResponse> = {
|
||||
id: 'neo4j_create',
|
||||
name: 'Neo4j Create',
|
||||
description:
|
||||
'Execute CREATE statements to add new nodes and relationships to Neo4j graph database',
|
||||
version: '1.0',
|
||||
|
||||
params: {
|
||||
host: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j server hostname or IP address',
|
||||
},
|
||||
port: {
|
||||
type: 'number',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j server port (default: 7687 for Bolt protocol)',
|
||||
},
|
||||
database: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Database name to connect to (e.g., "neo4j", "movies", "social")',
|
||||
},
|
||||
username: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j username',
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j password',
|
||||
},
|
||||
encryption: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Connection encryption mode (enabled, disabled)',
|
||||
},
|
||||
cypherQuery: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Cypher CREATE statement to execute (e.g., "CREATE (n:Person {name: $name, age: $age})", "CREATE (a)-[:KNOWS]->(b)")',
|
||||
},
|
||||
parameters: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Parameters for the Cypher query as a JSON object (e.g., {"name": "Alice", "age": 30})',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/neo4j/create',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
host: params.host,
|
||||
port: Number(params.port),
|
||||
database: params.database,
|
||||
username: params.username,
|
||||
password: params.password,
|
||||
encryption: params.encryption || 'disabled',
|
||||
cypherQuery: params.cypherQuery,
|
||||
parameters: params.parameters,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Neo4j create operation failed')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: data.message || 'Create operation executed successfully',
|
||||
summary: data.summary,
|
||||
},
|
||||
error: undefined,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: { type: 'string', description: 'Operation status message' },
|
||||
summary: {
|
||||
type: 'json',
|
||||
description: 'Creation summary with counters for nodes and relationships created',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
import type { Neo4jDeleteParams, Neo4jResponse } from '@/tools/neo4j/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const deleteTool: ToolConfig<Neo4jDeleteParams, Neo4jResponse> = {
|
||||
id: 'neo4j_delete',
|
||||
name: 'Neo4j Delete',
|
||||
description:
|
||||
'Execute DELETE or DETACH DELETE statements to remove nodes and relationships from Neo4j',
|
||||
version: '1.0',
|
||||
|
||||
params: {
|
||||
host: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j server hostname or IP address',
|
||||
},
|
||||
port: {
|
||||
type: 'number',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j server port (default: 7687 for Bolt protocol)',
|
||||
},
|
||||
database: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Database name to connect to (e.g., "neo4j", "movies", "social")',
|
||||
},
|
||||
username: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j username',
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j password',
|
||||
},
|
||||
encryption: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Connection encryption mode (enabled, disabled)',
|
||||
},
|
||||
cypherQuery: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Cypher query with MATCH and DELETE/DETACH DELETE statements (e.g., "MATCH (n:Person {name: $name}) DELETE n", "MATCH (n) DETACH DELETE n")',
|
||||
},
|
||||
parameters: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Parameters for the Cypher query as a JSON object (e.g., {"name": "Alice", "id": 123})',
|
||||
},
|
||||
detach: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether to use DETACH DELETE to remove relationships before deleting nodes',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/neo4j/delete',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
host: params.host,
|
||||
port: Number(params.port),
|
||||
database: params.database,
|
||||
username: params.username,
|
||||
password: params.password,
|
||||
encryption: params.encryption || 'disabled',
|
||||
cypherQuery: params.cypherQuery,
|
||||
parameters: params.parameters,
|
||||
detach: params.detach,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Neo4j delete operation failed')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: data.message || 'Delete operation executed successfully',
|
||||
summary: data.summary,
|
||||
},
|
||||
error: undefined,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: { type: 'string', description: 'Operation status message' },
|
||||
summary: {
|
||||
type: 'json',
|
||||
description: 'Delete summary with counters for nodes and relationships deleted',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import type { Neo4jExecuteParams, Neo4jResponse } from '@/tools/neo4j/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const executeTool: ToolConfig<Neo4jExecuteParams, Neo4jResponse> = {
|
||||
id: 'neo4j_execute',
|
||||
name: 'Neo4j Execute',
|
||||
description: 'Execute arbitrary Cypher queries on Neo4j graph database for complex operations',
|
||||
version: '1.0',
|
||||
|
||||
params: {
|
||||
host: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j server hostname or IP address',
|
||||
},
|
||||
port: {
|
||||
type: 'number',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j server port (default: 7687 for Bolt protocol)',
|
||||
},
|
||||
database: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Database name to connect to (e.g., "neo4j", "movies", "social")',
|
||||
},
|
||||
username: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j username',
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j password',
|
||||
},
|
||||
encryption: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Connection encryption mode (enabled, disabled)',
|
||||
},
|
||||
cypherQuery: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Cypher query to execute (e.g., "CALL db.labels()", "MATCH (n) RETURN count(n)", "CREATE INDEX FOR (n:Person) ON (n.name)")',
|
||||
},
|
||||
parameters: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Parameters for the Cypher query as a JSON object (e.g., {"name": "Alice", "limit": 100})',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/neo4j/execute',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
host: params.host,
|
||||
port: Number(params.port),
|
||||
database: params.database,
|
||||
username: params.username,
|
||||
password: params.password,
|
||||
encryption: params.encryption || 'disabled',
|
||||
cypherQuery: params.cypherQuery,
|
||||
parameters: params.parameters,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Neo4j execute operation failed')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: data.message || 'Query executed successfully',
|
||||
records: data.records || [],
|
||||
recordCount: data.recordCount || 0,
|
||||
summary: data.summary,
|
||||
},
|
||||
error: undefined,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: { type: 'string', description: 'Operation status message' },
|
||||
records: { type: 'array', description: 'Array of records returned from the query' },
|
||||
recordCount: { type: 'number', description: 'Number of records returned' },
|
||||
summary: { type: 'json', description: 'Execution summary with timing and counters' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { createTool } from './create'
|
||||
import { deleteTool } from './delete'
|
||||
import { executeTool } from './execute'
|
||||
import { introspectTool } from './introspect'
|
||||
import { mergeTool } from './merge'
|
||||
import { queryTool } from './query'
|
||||
import { updateTool } from './update'
|
||||
|
||||
export const neo4jCreateTool = createTool
|
||||
export const neo4jDeleteTool = deleteTool
|
||||
export const neo4jExecuteTool = executeTool
|
||||
export const neo4jIntrospectTool = introspectTool
|
||||
export const neo4jMergeTool = mergeTool
|
||||
export const neo4jQueryTool = queryTool
|
||||
export const neo4jUpdateTool = updateTool
|
||||
export * from './types'
|
||||
@@ -0,0 +1,103 @@
|
||||
import type { Neo4jIntrospectParams, Neo4jIntrospectResponse } from '@/tools/neo4j/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const introspectTool: ToolConfig<Neo4jIntrospectParams, Neo4jIntrospectResponse> = {
|
||||
id: 'neo4j_introspect',
|
||||
name: 'Neo4j Introspect',
|
||||
description:
|
||||
'Introspect a Neo4j database to discover its schema including node labels, relationship types, properties, constraints, and indexes.',
|
||||
version: '1.0',
|
||||
|
||||
params: {
|
||||
host: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j server hostname or IP address',
|
||||
},
|
||||
port: {
|
||||
type: 'number',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j server port (default: 7687 for Bolt protocol)',
|
||||
},
|
||||
database: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Database name to connect to (e.g., "neo4j", "movies", "social")',
|
||||
},
|
||||
username: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j username',
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j password',
|
||||
},
|
||||
encryption: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Connection encryption mode (enabled, disabled)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/neo4j/introspect',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
host: params.host,
|
||||
port: Number(params.port),
|
||||
database: params.database,
|
||||
username: params.username,
|
||||
password: params.password,
|
||||
encryption: params.encryption || 'disabled',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Neo4j introspection failed')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: data.message || 'Introspection completed successfully',
|
||||
labels: data.labels || [],
|
||||
relationshipTypes: data.relationshipTypes || [],
|
||||
nodeSchemas: data.nodeSchemas || [],
|
||||
relationshipSchemas: data.relationshipSchemas || [],
|
||||
constraints: data.constraints || [],
|
||||
indexes: data.indexes || [],
|
||||
},
|
||||
error: undefined,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: { type: 'string', description: 'Operation status message' },
|
||||
labels: { type: 'array', description: 'Array of node labels in the database' },
|
||||
relationshipTypes: {
|
||||
type: 'array',
|
||||
description: 'Array of relationship types in the database',
|
||||
},
|
||||
nodeSchemas: { type: 'array', description: 'Array of node schemas with their properties' },
|
||||
relationshipSchemas: {
|
||||
type: 'array',
|
||||
description: 'Array of relationship schemas with their properties',
|
||||
},
|
||||
constraints: { type: 'array', description: 'Array of database constraints' },
|
||||
indexes: { type: 'array', description: 'Array of database indexes' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import type { Neo4jMergeParams, Neo4jResponse } from '@/tools/neo4j/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const mergeTool: ToolConfig<Neo4jMergeParams, Neo4jResponse> = {
|
||||
id: 'neo4j_merge',
|
||||
name: 'Neo4j Merge',
|
||||
description:
|
||||
'Execute MERGE statements to find or create nodes and relationships in Neo4j (upsert operation)',
|
||||
version: '1.0',
|
||||
|
||||
params: {
|
||||
host: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j server hostname or IP address',
|
||||
},
|
||||
port: {
|
||||
type: 'number',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j server port (default: 7687 for Bolt protocol)',
|
||||
},
|
||||
database: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Database name to connect to (e.g., "neo4j", "movies", "social")',
|
||||
},
|
||||
username: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j username',
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j password',
|
||||
},
|
||||
encryption: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Connection encryption mode (enabled, disabled)',
|
||||
},
|
||||
cypherQuery: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Cypher MERGE statement to execute (e.g., "MERGE (n:Person {name: $name}) ON CREATE SET n.created = timestamp()", "MERGE (a)-[r:KNOWS]->(b)")',
|
||||
},
|
||||
parameters: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Parameters for the Cypher query as a JSON object (e.g., {"name": "Alice", "email": "alice@example.com"})',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/neo4j/merge',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
host: params.host,
|
||||
port: Number(params.port),
|
||||
database: params.database,
|
||||
username: params.username,
|
||||
password: params.password,
|
||||
encryption: params.encryption || 'disabled',
|
||||
cypherQuery: params.cypherQuery,
|
||||
parameters: params.parameters,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Neo4j merge operation failed')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: data.message || 'Merge operation executed successfully',
|
||||
summary: data.summary,
|
||||
},
|
||||
error: undefined,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: { type: 'string', description: 'Operation status message' },
|
||||
summary: {
|
||||
type: 'json',
|
||||
description: 'Merge summary with counters for nodes/relationships created or matched',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
import type { Neo4jQueryParams, Neo4jResponse } from '@/tools/neo4j/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const queryTool: ToolConfig<Neo4jQueryParams, Neo4jResponse> = {
|
||||
id: 'neo4j_query',
|
||||
name: 'Neo4j Query',
|
||||
description:
|
||||
'Execute MATCH queries to read nodes and relationships from Neo4j graph database. For best performance and to prevent large result sets, include LIMIT in your query (e.g., "MATCH (n:User) RETURN n LIMIT 100") or use LIMIT $limit with a limit parameter.',
|
||||
version: '1.0',
|
||||
|
||||
params: {
|
||||
host: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j server hostname or IP address',
|
||||
},
|
||||
port: {
|
||||
type: 'number',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j server port (default: 7687 for Bolt protocol)',
|
||||
},
|
||||
database: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Database name to connect to (e.g., "neo4j", "movies", "social")',
|
||||
},
|
||||
username: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j username',
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j password',
|
||||
},
|
||||
encryption: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Connection encryption mode (enabled, disabled)',
|
||||
},
|
||||
cypherQuery: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Cypher query to execute (e.g., "MATCH (n:Person) RETURN n LIMIT 10", "MATCH (a)-[r]->(b) WHERE a.name = $name RETURN a, r, b")',
|
||||
},
|
||||
parameters: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Parameters for the Cypher query as a JSON object. Use for any dynamic values including LIMIT (e.g., query: "MATCH (n) RETURN n LIMIT $limit", parameters: {limit: 100}).',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/neo4j/query',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
host: params.host,
|
||||
port: Number(params.port),
|
||||
database: params.database,
|
||||
username: params.username,
|
||||
password: params.password,
|
||||
encryption: params.encryption || 'disabled',
|
||||
cypherQuery: params.cypherQuery,
|
||||
parameters: params.parameters,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Neo4j query failed')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: data.message || 'Query executed successfully',
|
||||
records: data.records || [],
|
||||
recordCount: data.recordCount || 0,
|
||||
summary: data.summary,
|
||||
},
|
||||
error: undefined,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: { type: 'string', description: 'Operation status message' },
|
||||
records: { type: 'array', description: 'Array of records returned from the query' },
|
||||
recordCount: { type: 'number', description: 'Number of records returned' },
|
||||
summary: { type: 'json', description: 'Query execution summary with timing and counters' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
import type { ToolResponse } from '@/tools/types'
|
||||
|
||||
export interface Neo4jConnectionConfig {
|
||||
host: string
|
||||
port: number
|
||||
database: string
|
||||
username: string
|
||||
password: string
|
||||
encryption?: 'enabled' | 'disabled'
|
||||
}
|
||||
|
||||
export interface Neo4jQueryParams extends Neo4jConnectionConfig {
|
||||
cypherQuery: string
|
||||
parameters?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export interface Neo4jCreateParams extends Neo4jConnectionConfig {
|
||||
cypherQuery: string
|
||||
parameters?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export interface Neo4jMergeParams extends Neo4jConnectionConfig {
|
||||
cypherQuery: string
|
||||
parameters?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export interface Neo4jUpdateParams extends Neo4jConnectionConfig {
|
||||
cypherQuery: string
|
||||
parameters?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export interface Neo4jDeleteParams extends Neo4jConnectionConfig {
|
||||
cypherQuery: string
|
||||
parameters?: Record<string, unknown>
|
||||
detach?: boolean
|
||||
}
|
||||
|
||||
export interface Neo4jExecuteParams extends Neo4jConnectionConfig {
|
||||
cypherQuery: string
|
||||
parameters?: Record<string, unknown>
|
||||
}
|
||||
|
||||
interface Neo4jBaseResponse extends ToolResponse {
|
||||
output: {
|
||||
message: string
|
||||
records?: unknown[]
|
||||
recordCount?: number
|
||||
summary?: {
|
||||
resultAvailableAfter: number
|
||||
resultConsumedAfter: number
|
||||
counters?: {
|
||||
nodesCreated: number
|
||||
nodesDeleted: number
|
||||
relationshipsCreated: number
|
||||
relationshipsDeleted: number
|
||||
propertiesSet: number
|
||||
labelsAdded: number
|
||||
labelsRemoved: number
|
||||
indexesAdded: number
|
||||
indexesRemoved: number
|
||||
constraintsAdded: number
|
||||
constraintsRemoved: number
|
||||
}
|
||||
}
|
||||
}
|
||||
error?: string
|
||||
}
|
||||
|
||||
interface Neo4jQueryResponse extends Neo4jBaseResponse {}
|
||||
interface Neo4jCreateResponse extends Neo4jBaseResponse {}
|
||||
interface Neo4jMergeResponse extends Neo4jBaseResponse {}
|
||||
interface Neo4jUpdateResponse extends Neo4jBaseResponse {}
|
||||
interface Neo4jDeleteResponse extends Neo4jBaseResponse {}
|
||||
interface Neo4jExecuteResponse extends Neo4jBaseResponse {}
|
||||
export interface Neo4jResponse extends Neo4jBaseResponse {}
|
||||
|
||||
export interface Neo4jIntrospectParams extends Neo4jConnectionConfig {}
|
||||
|
||||
export interface Neo4jNodeSchema {
|
||||
label: string
|
||||
properties: Array<{ name: string; types: string[] }>
|
||||
}
|
||||
|
||||
export interface Neo4jRelationshipSchema {
|
||||
type: string
|
||||
properties: Array<{ name: string; types: string[] }>
|
||||
}
|
||||
|
||||
export interface Neo4jIntrospectResponse extends ToolResponse {
|
||||
output: {
|
||||
message: string
|
||||
labels: string[]
|
||||
relationshipTypes: string[]
|
||||
nodeSchemas: Neo4jNodeSchema[]
|
||||
relationshipSchemas: Neo4jRelationshipSchema[]
|
||||
constraints: Array<{ name: string; type: string; entityType: string; properties: string[] }>
|
||||
indexes: Array<{ name: string; type: string; entityType: string; properties: string[] }>
|
||||
}
|
||||
error?: string
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
import type { Neo4jResponse, Neo4jUpdateParams } from '@/tools/neo4j/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const updateTool: ToolConfig<Neo4jUpdateParams, Neo4jResponse> = {
|
||||
id: 'neo4j_update',
|
||||
name: 'Neo4j Update',
|
||||
description:
|
||||
'Execute SET statements to update properties of existing nodes and relationships in Neo4j',
|
||||
version: '1.0',
|
||||
|
||||
params: {
|
||||
host: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j server hostname or IP address',
|
||||
},
|
||||
port: {
|
||||
type: 'number',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j server port (default: 7687 for Bolt protocol)',
|
||||
},
|
||||
database: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Database name to connect to (e.g., "neo4j", "movies", "social")',
|
||||
},
|
||||
username: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j username',
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Neo4j password',
|
||||
},
|
||||
encryption: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Connection encryption mode (enabled, disabled)',
|
||||
},
|
||||
cypherQuery: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Cypher query with MATCH and SET statements to update properties (e.g., "MATCH (n:Person {name: $name}) SET n.age = $age", "MATCH (n) WHERE n.id = $id SET n += $props")',
|
||||
},
|
||||
parameters: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Parameters for the Cypher query as a JSON object (e.g., {"name": "Alice", "age": 31, "props": {"city": "NYC"}})',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/neo4j/update',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
host: params.host,
|
||||
port: Number(params.port),
|
||||
database: params.database,
|
||||
username: params.username,
|
||||
password: params.password,
|
||||
encryption: params.encryption || 'disabled',
|
||||
cypherQuery: params.cypherQuery,
|
||||
parameters: params.parameters,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Neo4j update operation failed')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: data.message || 'Update operation executed successfully',
|
||||
summary: data.summary,
|
||||
},
|
||||
error: undefined,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: { type: 'string', description: 'Operation status message' },
|
||||
summary: { type: 'json', description: 'Update summary with counters for properties set' },
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user