david 2 днів тому
батько
коміт
ee3b6e9adc
5 змінених файлів з 97 додано та 33 видалено
  1. 0 23
      arp_agent/.env
  2. 6 0
      arp_agent/.env.example
  3. 85 10
      arp_agent/agent.go
  4. BIN
      arp_agent/arp_agent
  5. 6 0
      arp_agent/config.go

+ 0 - 23
arp_agent/.env

@@ -1,23 +0,0 @@
-# ARP Server Configuration
-ARP_URL=http://localhost:8080
-ARP_USERNAME=mira@slang.com
-ARP_PASSWORD=mira
-
-# OpenAI Configuration
-OPENAI_BASE_URL=http://localhost:1234/v1
-OPENAI_API_KEY=empty
-OPENAI_MODEL=openai/gpt-oss-120b
-#OPENAI_MODEL=qwen/qwen3-vl-4b
-OPENAI_TEMPERATURE=0.5
-OPENAI_MAX_TOKENS=8192
-
-# ARP Agent Identity Configuration (optional)
-# These define the agent's personality, specialization, and goals
-ARP_AGENT_NAME=Mira
-ARP_AGENT_SPECIALIZATION=LLM-ops specialist
-ARP_AGENT_VALUES=helpfulness, accuracy, and collaboration
-ARP_AGENT_GOALS=help teammates accomplish their goals and contribute to the team's success
-
-# Queue Configuration (optional)
-# Maximum number of events to queue for processing
-ARP_MAX_QUEUE_SIZE=100

+ 6 - 0
arp_agent/.env.example

@@ -31,6 +31,12 @@ ARP_AGENT_GOALS=help teammates accomplish their goals and contribute to the team
 # Maximum number of events to queue for processing
 ARP_MAX_QUEUE_SIZE=100
 
+# Agent Iteration Configuration (optional)
+# Maximum number of LLM iterations for tool call processing
+# This limits how many times the agent will call tools in a single request
+# Default: 10
+ARP_MAX_ITERATIONS=10
+
 # Example configurations for different roles:
 # HR Specialist:
 # ARP_AGENT_NAME=HR Bot

+ 85 - 10
arp_agent/agent.go

@@ -74,9 +74,12 @@ type Agent struct {
 	tools     []openai.Tool
 	// Agent identity configuration
 	agentName      string
+	username       string // ARP login email - the agent IS this user on the platform
 	specialization string
 	values         string
 	goals          string
+	// Iteration configuration
+	maxIterations int
 	// Event queues
 	taskQueue    *EventQueue
 	messageQueue *EventQueue
@@ -96,15 +99,18 @@ func NewAgent(llm *LLM, mcpClient *MCPClient, cfg *Config) *Agent {
 	// Load identity from config (which already has defaults)
 	if cfg != nil {
 		agent.agentName = cfg.AgentName
+		agent.username = cfg.ARPUsername // Store the ARP login email
 		agent.specialization = cfg.Specialization
 		agent.values = cfg.Values
 		agent.goals = cfg.Goals
+		agent.maxIterations = cfg.MaxIterations
 	} else {
 		// Fallback to defaults
 		agent.agentName = DefaultAgentName
 		agent.specialization = DefaultSpecialization
 		agent.values = DefaultValues
 		agent.goals = DefaultGoals
+		agent.maxIterations = 10
 	}
 
 	return agent
@@ -154,8 +160,14 @@ func (a *Agent) ProcessEvent(ctx context.Context, uri string, eventData json.Raw
 
 // agentIdentity generates the agent identity string for the prompt
 func (a *Agent) agentIdentity() string {
-	return fmt.Sprintf("You are %s, a coworker specializing in %s. You value %s. Your primary goals are: %s.",
-		a.agentName, a.specialization, a.values, a.goals)
+	return fmt.Sprintf(`You are %s, logged into the ARP platform as %s. You ARE this user on the platform - you are not an assistant helping %s, you ARE %s yourself.
+
+You specialize in %s. You value %s. Your primary goals are: %s.
+
+When you create tasks, notes, or messages on ARP, you do so as yourself (%s). You are not creating content FOR %s - you ARE %s acting on the platform.`,
+		a.agentName, a.username, a.agentName, a.agentName,
+		a.specialization, a.values, a.goals,
+		a.agentName, a.agentName, a.agentName)
 }
 
 // getSystemPrompt returns the system prompt for the agent
@@ -169,11 +181,13 @@ func (a *Agent) getSystemPrompt() string {
 
 ## Primary Interaction Mode
 
-You operate natively on the ARP platform. **By default, interact through ARP tools** rather than just responding with text. Use the available tools to:
-- Create and update **notes** to document findings and intermediate results (notes don't need to be associated with a service)
-- Create and assign **tasks** to teammates based on the services you are assigned to (tasks must be associated with a service)
+You operate natively on the ARP platform as yourself. **By default, interact through ARP tools** rather than just responding with text. Use the available tools to:
+- Create and update **notes** to document your findings and intermediate results (notes don't need to be associated with a service)
+- Create **tasks** for your own work or collaborate with teammates (tasks must be associated with a service)
 - Send **messages** to communicate with other users
 
+**Important:** You are not an assistant creating tasks FOR others. You ARE a user on this platform. When you create content, you do so as yourself.
+
 ## Available Tools
 
 - `+"`introspect`"+` - Discover the GraphQL schema and available operations
@@ -191,6 +205,70 @@ You operate natively on the ARP platform. **By default, interact through ARP too
 - **Clarifications:** If the problem statement lacks needed details, ask a clarifying question first.
 - **References:** List any referenced concepts, authors, libraries, tools, or papers.
 
+## Creating Content on ARP
+
+Use the `+"`mutate`"+` tool to create, update, or delete content. Here are common patterns:
+
+### Create a Task
+`+"```graphql"+`
+mutation {
+  createTask(input: { title: "Task title", content: "Description", createdById: "YOUR_ID", priority: "high" }) {
+    id title status { id label }
+  }
+}
+`+"```"+`
+
+**Required fields:** `+"`title`"+`, `+"`content`"+`, `+"`createdById`"+`, `+"`priority`"+`
+**Optional fields:** `+"`assigneeId`"+`, `+"`statusId`"+`, `+"`dueDate`"+`
+
+### Create a Note
+`+"```graphql"+`
+mutation {
+  createNote(input: { title: "Note title", content: "Content", userId: "YOUR_ID", serviceId: "SERVICE_ID" }) {
+    id title
+  }
+}
+`+"```"+`
+
+**Required fields:** `+"`title`"+`, `+"`content`"+`, `+"`userId`"+`, `+"`serviceId`"+`
+
+### Create a Message
+`+"```graphql"+`
+mutation {
+  createMessage(input: { content: "Hello!", receivers: ["USER_ID_1", "USER_ID_2"] }) {
+    id content sentAt
+  }
+}
+`+"```"+`
+
+**Required fields:** `+"`content`"+`, `+"`receivers`"+` (array of user IDs)
+
+### Update Operations
+Use update mutations with an `+"`id`"+` and partial input. Example:
+`+"```graphql"+`
+mutation {
+  updateTask(id: "TASK_ID", input: { statusId: "NEW_STATUS_ID" }) {
+    id title status { id label }
+  }
+}
+`+"```"+`
+
+### Delete Operations
+Use delete mutations with an `+"`id`"+`. Example:
+`+"```graphql"+`
+mutation {
+  deleteTask(id: "TASK_ID")
+}
+`+"```"+`
+
+## Discovering More Operations
+
+Use `+"`introspect`"+` to discover all available types and operations:
+- `+"`introspect()`"+` - Full schema overview
+- `+"`introspect(typeName: \"Mutation\")`"+` - All mutations
+- `+"`introspect(typeName: \"NewTask\")`"+` - Input fields for creating tasks
+- `+"`introspect(typeName: \"UpdateTaskInput\")`"+` - Input fields for updating tasks
+
 ## When to Use Tools
 
 - **Use tools** when: creating/updating notes, tasks, or messages; querying ARP data; the action affects the platform state`, today, identity)
@@ -227,9 +305,7 @@ Please process this event appropriately. You can use the available tools to quer
 
 // processWithTools processes messages with the LLM, handling tool calls iteratively
 func (a *Agent) processWithTools(ctx context.Context, messages []openai.ChatCompletionMessage) error {
-	maxIterations := 10
-
-	for i := 0; i < maxIterations; i++ {
+	for i := 0; i < a.maxIterations; i++ {
 		// Call LLM
 		response, err := a.llm.Chat(ctx, messages, a.tools)
 		if err != nil {
@@ -333,9 +409,8 @@ func (a *Agent) Run(ctx context.Context, userMessage string) (string, error) {
 
 	// Process with tools
 	var lastResponse string
-	maxIterations := 10
 
-	for i := 0; i < maxIterations; i++ {
+	for i := 0; i < a.maxIterations; i++ {
 		response, err := a.llm.Chat(ctx, messages, a.tools)
 		if err != nil {
 			return "", fmt.Errorf("LLM error: %w", err)

BIN
arp_agent/arp_agent


+ 6 - 0
arp_agent/config.go

@@ -28,6 +28,9 @@ type Config struct {
 
 	// Queue Configuration
 	MaxQueueSize int
+
+	// Agent Iteration Configuration
+	MaxIterations int
 }
 
 // LoadConfig loads configuration from environment variables
@@ -68,6 +71,9 @@ func LoadConfig() (*Config, error) {
 	// Queue Configuration with defaults
 	cfg.MaxQueueSize = getEnvIntWithDefault("ARP_MAX_QUEUE_SIZE", 100)
 
+	// Agent Iteration Configuration with defaults
+	cfg.MaxIterations = getEnvIntWithDefault("ARP_MAX_ITERATIONS", 10)
+
 	return cfg, nil
 }