Agent Resource Platform - this is an exploration into what a backbone for human-agent interaction in a business context might look like.
|
|
hai 4 horas | |
|---|---|---|
| arp_agent | hai 4 horas | |
| arp_cli | hai 22 horas | |
| auth | hai 1 semana | |
| graph | hai 4 horas | |
| logging | hai 1 semana | |
| mcp | hai 4 horas | |
| models | hai 4 horas | |
| workflow | hai 4 horas | |
| .gitignore | hai 4 horas | |
| CLIENT_GUIDE.md | hai 4 horas | |
| README.md | hai 4 horas | |
| go.mod | hai 1 semana | |
| go.sum | hai 1 semana | |
| gqlgen.yml | hai 1 semana | |
| init_prod.sql | hai 4 horas | |
| server.go | hai 4 horas |
A GraphQL-based coordination system for users and agents to collaborate on services, tasks, and workflows.
ARP (Agent Resource Platform) is a coordination backend that enables human users and AI agents to work together on shared services. It provides:
┌─────────────────────────────────────────────────────────────┐
│ GraphQL API │
│ (gqlgen - schema-first, type-safe resolvers) │
├─────────────────────────────────────────────────────────────┤
│ Auth Middleware │
│ (JWT tokens, permission checks) │
├─────────────────────────────────────────────────────────────┤
│ GORM Models │
│ User → Role → Permission │
│ Service → Task → TaskStatus │
│ Channel → Message │
│ Note │
├─────────────────────────────────────────────────────────────┤
│ SQLite Database │
│ (arp.db - can be swapped for PostgreSQL/MySQL) │
└─────────────────────────────────────────────────────────────┘
# Clone and run
go run server.go
# Server starts on http://localhost:8080
go test ./... -v
go run server.go &
# Server runs on http://localhost:8080
Use GraphQL introspection to discover the API schema:
# Get all types in the schema
curl -s -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-d '{"query":"{ __schema { types { name kind description fields { name type { name kind ofType { name } } } } } }"}' | jq
# Get all queries and mutations
curl -s -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-d '{"query":"{ __schema { queryType { fields { name description } } mutationType { fields { name description } } } }"}' | jq
Run the SQL bootstrap script to create permissions, roles, task statuses, and an admin user:
# Initialize the database with seed data
sqlite3 arp.db < init.sql
# Verify the data was created
sqlite3 arp.db "SELECT name FROM roles;"
# Output:
# admin
# manager
# user
sqlite3 arp.db "SELECT email FROM users;"
# Output:
# admin@example.com
The init.sql script creates:
admin@example.com and password secret123# Login to get JWT token
TOKEN=$(curl -s -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-d '{"query":"mutation { login(email: \"admin@example.com\", password: \"secret123\") { token user { email roles { name } } } }"}' | jq -r '.data.login.token')
echo "Token: $TOKEN"
# Get all services with authentication
curl -s -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"query":"{ services { id name description createdAt participants { email } tasks { title status { label } } } }"}' | jq
# Create a new service
curl -s -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"query":"mutation { createService(input: {name: \"Project Alpha\", description: \"New project\", createdById: \"1\", participants: [\"1\"]}) { id name } }"}' | jq
# Get a specific service
curl -s -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"query":"{ service(id: \"1\") { id name description createdBy { email } participants { email } tasks { id title priority status { code label } } } }"}' | jq
The system uses a hierarchical permission model:
User ─┬─ has many ─→ Role ─┬─ has many ─→ Permission
│ │
└─ e.g., "admin" └─ e.g., "service:create"
| Operation | Required Permission |
|---|---|
| Update User | user:update |
| Delete User | user:delete |
| Update Task | task:update |
| Delete Task | task:delete |
| Update Note | note:update |
| Delete Note | note:delete |
| Update Service | service:update |
| Delete Service | service:delete |
| ... | ... |
# Include JWT token in Authorization header
curl -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"query":"..."}'
task:create)type Query {
users: [User!]!
user(id: ID!): User
services: [Service!]!
service(id: ID!): Service
tasks: [Task!]!
task(id: ID!): Task
roles: [Role!]!
permissions: [Permission!]!
# ... more queries
}
type Mutation {
login(email: String!, password: String!): AuthPayload!
createUser(input: NewUser!): User!
createService(input: NewService!): Service!
createTask(input: NewTask!): Task!
# ... more mutations
}
The workflow engine enables you to define complex multi-step processes as JSON-based DAGs (Directed Acyclic Graphs). Each node in the DAG represents a task or decision point, and dependencies between nodes are automatically resolved.
Workflows are defined as JSON with a nodes object where each key is a unique node identifier:
{
"nodes": {
"start": {
"type": "task",
"title": "Initial Review",
"content": "Review the initial request",
"assignee": "1",
"dependsOn": []
},
"analysis": {
"type": "task",
"title": "Data Analysis",
"content": "Analyze the data",
"assignee": "2",
"dependsOn": ["start"]
},
"approval": {
"type": "task",
"title": "Manager Approval",
"content": "Get manager approval",
"assignee": "3",
"dependsOn": ["analysis"]
},
"end": {
"type": "task",
"title": "Complete",
"content": "Mark workflow as complete",
"assignee": "1",
"dependsOn": ["approval"]
}
}
}
| Operation | Required Permission |
|---|---|
| Create Workflow Template | workflow:create |
| Update Workflow Template | workflow:manage |
| Delete Workflow Template | workflow:manage |
| Start Workflow | workflow:start |
| Cancel Workflow | workflow:manage |
| Retry Node | workflow:intervene |
| View Workflows | workflow:view |
| Type | Description |
|---|---|
task |
Creates a task for a user to complete |
condition |
Evaluates conditions to determine next steps |
parallel |
Spawns multiple concurrent branches |
join |
Waits for multiple branches to complete |
trigger |
Starts the workflow automatically |
When a task associated with a workflow node is marked as "done", the workflow engine automatically:
This enables workflows to progress automatically as users complete their assigned tasks.
# Create a workflow template
curl -s -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"query": "mutation { createWorkflowTemplate(input: {name: \"Onboarding\", description: \"New employee onboarding\", definition: \"{\\\"nodes\\\":{\\\"start\\\":{\\\"type\\\":\\\"task\\\",\\\"title\\\":\\\"Welcome\\\",\\\"content\\\":\\\"Send welcome email\\\",\\\"assignee\\\":\\\"1\\\",\\\"dependsOn\\\":[]}}}\"}) { id name }"
}' | jq
# Start a workflow instance
curl -s -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"query": "mutation { startWorkflow(templateId: \"1\", input: {serviceId: \"1\", context: \"New hire onboarding\"}) { id status template { name } } }"
}' | jq
# Get all workflow instances
curl -s -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"query":"{ workflowInstances { id status template { name } service { name } } }"}' | jq
# Retry a failed workflow node
curl -s -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"query":"mutation { retryWorkflowNode(nodeId: \"1\") { id nodeKey status retryCount } }"}' | jq
| Variable | Default | Description |
|---|---|---|
JWT_SECRET |
your-secret-key-change-in-production |
Secret for JWT signing |