|
@@ -74,9 +74,12 @@ type Agent struct {
|
|
|
tools []openai.Tool
|
|
tools []openai.Tool
|
|
|
// Agent identity configuration
|
|
// Agent identity configuration
|
|
|
agentName string
|
|
agentName string
|
|
|
|
|
+ username string // ARP login email - the agent IS this user on the platform
|
|
|
specialization string
|
|
specialization string
|
|
|
values string
|
|
values string
|
|
|
goals string
|
|
goals string
|
|
|
|
|
+ // Iteration configuration
|
|
|
|
|
+ maxIterations int
|
|
|
// Event queues
|
|
// Event queues
|
|
|
taskQueue *EventQueue
|
|
taskQueue *EventQueue
|
|
|
messageQueue *EventQueue
|
|
messageQueue *EventQueue
|
|
@@ -96,15 +99,18 @@ func NewAgent(llm *LLM, mcpClient *MCPClient, cfg *Config) *Agent {
|
|
|
// Load identity from config (which already has defaults)
|
|
// Load identity from config (which already has defaults)
|
|
|
if cfg != nil {
|
|
if cfg != nil {
|
|
|
agent.agentName = cfg.AgentName
|
|
agent.agentName = cfg.AgentName
|
|
|
|
|
+ agent.username = cfg.ARPUsername // Store the ARP login email
|
|
|
agent.specialization = cfg.Specialization
|
|
agent.specialization = cfg.Specialization
|
|
|
agent.values = cfg.Values
|
|
agent.values = cfg.Values
|
|
|
agent.goals = cfg.Goals
|
|
agent.goals = cfg.Goals
|
|
|
|
|
+ agent.maxIterations = cfg.MaxIterations
|
|
|
} else {
|
|
} else {
|
|
|
// Fallback to defaults
|
|
// Fallback to defaults
|
|
|
agent.agentName = DefaultAgentName
|
|
agent.agentName = DefaultAgentName
|
|
|
agent.specialization = DefaultSpecialization
|
|
agent.specialization = DefaultSpecialization
|
|
|
agent.values = DefaultValues
|
|
agent.values = DefaultValues
|
|
|
agent.goals = DefaultGoals
|
|
agent.goals = DefaultGoals
|
|
|
|
|
+ agent.maxIterations = 10
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return agent
|
|
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
|
|
// agentIdentity generates the agent identity string for the prompt
|
|
|
func (a *Agent) agentIdentity() string {
|
|
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
|
|
// getSystemPrompt returns the system prompt for the agent
|
|
@@ -169,11 +181,13 @@ func (a *Agent) getSystemPrompt() string {
|
|
|
|
|
|
|
|
## Primary Interaction Mode
|
|
## 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
|
|
- 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
|
|
## Available Tools
|
|
|
|
|
|
|
|
- `+"`introspect`"+` - Discover the GraphQL schema and available operations
|
|
- `+"`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.
|
|
- **Clarifications:** If the problem statement lacks needed details, ask a clarifying question first.
|
|
|
- **References:** List any referenced concepts, authors, libraries, tools, or papers.
|
|
- **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
|
|
## When to Use Tools
|
|
|
|
|
|
|
|
- **Use tools** when: creating/updating notes, tasks, or messages; querying ARP data; the action affects the platform state`, today, identity)
|
|
- **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
|
|
// processWithTools processes messages with the LLM, handling tool calls iteratively
|
|
|
func (a *Agent) processWithTools(ctx context.Context, messages []openai.ChatCompletionMessage) error {
|
|
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
|
|
// Call LLM
|
|
|
response, err := a.llm.Chat(ctx, messages, a.tools)
|
|
response, err := a.llm.Chat(ctx, messages, a.tools)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -333,9 +409,8 @@ func (a *Agent) Run(ctx context.Context, userMessage string) (string, error) {
|
|
|
|
|
|
|
|
// Process with tools
|
|
// Process with tools
|
|
|
var lastResponse string
|
|
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)
|
|
response, err := a.llm.Chat(ctx, messages, a.tools)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return "", fmt.Errorf("LLM error: %w", err)
|
|
return "", fmt.Errorf("LLM error: %w", err)
|