Enhance Robot Execution Management and Documentation
- Updated the DESIGN.md to clarify the relationship between robots and executions, emphasizing that each trigger creates a new execution mapped to a job.Job for monitoring. - Revised the RobotState struct to include fields for tracking multiple running executions and their IDs, improving concurrency management. - Enhanced the TECHNICAL.md to reflect the global robot object for static methods, streamlining the API usage for robot management. - Improved TypeScript interfaces to align with the new execution tracking structure, ensuring consistency across documentation. - Added detailed comments and examples for job creation and execution handling, clarifying the integration of the job system within the robot's functionality.
This commit is contained in:
parent
8bcf7d2303
commit
3915ac493c
2 changed files with 189 additions and 110 deletions
|
|
@ -663,7 +663,9 @@ stateDiagram-v2
|
||||||
|
|
||||||
### 7.1 Job System
|
### 7.1 Job System
|
||||||
|
|
||||||
Each agent = 1 Job. Each run = 1 Execution.
|
**Relationship:** 1 Robot : N Executions (concurrent), 1 Execution = 1 job.Job
|
||||||
|
|
||||||
|
Each trigger creates a new Execution, mapped to a `job.Job` for monitoring.
|
||||||
|
|
||||||
```
|
```
|
||||||
┌─────────────────────────────────────────────────────────────────┐
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
|
@ -807,55 +809,65 @@ type ExecutionResult struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type RobotState struct {
|
type RobotState struct {
|
||||||
MemberID string // member_id from __yao.member
|
MemberID string // member_id from __yao.member
|
||||||
Status RobotStatus // idle | working | paused | error | maintenance
|
Status RobotStatus // idle | working | paused | error | maintenance
|
||||||
LastRun time.Time
|
LastRun time.Time
|
||||||
NextRun time.Time
|
NextRun time.Time
|
||||||
RunningID string // current execution ID if working
|
Running int // current running execution count
|
||||||
|
MaxRunning int // max concurrent executions (from Quota.Max)
|
||||||
|
RunningIDs []string // list of running execution IDs
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 8.3 Execution (Uses Job System)
|
### 8.3 Execution (Uses Job System)
|
||||||
|
|
||||||
No separate `autonomous_executions` table. Uses existing Job system:
|
No separate `autonomous_executions` table. Uses existing Job system.
|
||||||
|
|
||||||
|
**Each trigger creates a new job.Job:**
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// On robot member create - use Once/Cron/Daemon based on clock mode
|
// On each trigger (clock/human/event), create a new Job
|
||||||
|
execID := gonanoid.Must()
|
||||||
j, _ := job.Once(job.GOROUTINE, map[string]interface{}{
|
j, _ := job.Once(job.GOROUTINE, map[string]interface{}{
|
||||||
"job_id": "robot_" + memberID,
|
"job_id": "robot_exec_" + execID, // unique per execution
|
||||||
"category_id": "autonomous_robot",
|
"category_id": "autonomous_robot",
|
||||||
"name": member.DisplayName,
|
"name": fmt.Sprintf("%s - %s", member.DisplayName, triggerType),
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"member_id": memberID,
|
||||||
|
"team_id": teamID,
|
||||||
|
"trigger_type": triggerType,
|
||||||
|
"exec_id": execID,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
job.SaveJob(j)
|
job.SaveJob(j)
|
||||||
|
|
||||||
// Add execution with config
|
// Configure and start
|
||||||
exec := &job.Execution{
|
j.ExecutionConfig = &job.ExecutionConfig{
|
||||||
ExecutionID: gonanoid.Must(),
|
Type: job.ExecutionTypeProcess,
|
||||||
JobID: j.JobID,
|
ProcessName: "robot.Execute",
|
||||||
Status: "queued",
|
ProcessArgs: []interface{}{memberID, execID, triggerData},
|
||||||
TriggerCategory: string(TriggerClock), // or TriggerHuman, TriggerEvent
|
|
||||||
ExecutionConfig: &job.ExecutionConfig{
|
|
||||||
Type: job.ExecutionTypeProcess,
|
|
||||||
ProcessName: "robot.Execute",
|
|
||||||
ProcessArgs: []interface{}{memberID, triggerData},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
job.SaveExecution(exec)
|
|
||||||
|
|
||||||
// Start execution
|
|
||||||
j.Push()
|
j.Push()
|
||||||
|
```
|
||||||
|
|
||||||
// Query history
|
**Query executions for a robot:**
|
||||||
|
|
||||||
|
```go
|
||||||
|
// List all executions for a robot member
|
||||||
param := model.QueryParam{
|
param := model.QueryParam{
|
||||||
Wheres: []model.QueryWhere{{Column: "job_id", Value: j.JobID}},
|
Wheres: []model.QueryWhere{
|
||||||
|
{Column: "category_id", Value: "autonomous_robot"},
|
||||||
|
{Column: "metadata->member_id", Value: memberID},
|
||||||
|
},
|
||||||
|
Orders: []model.QueryOrder{{Column: "created_at", Option: "desc"}},
|
||||||
}
|
}
|
||||||
execs, _ := job.ListExecutions(param, 1, 10)
|
jobs, _ := job.ListJobs(param, 1, 10)
|
||||||
```
|
```
|
||||||
|
|
||||||
**Query examples:**
|
**Query examples:**
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// List robot jobs
|
// List all robot jobs (all robots, all executions)
|
||||||
param := model.QueryParam{
|
param := model.QueryParam{
|
||||||
Wheres: []model.QueryWhere{
|
Wheres: []model.QueryWhere{
|
||||||
{Column: "category_id", Value: "autonomous_robot"},
|
{Column: "category_id", Value: "autonomous_robot"},
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ yao/agent/robot/
|
||||||
├── api/ # All API forms
|
├── api/ # All API forms
|
||||||
│ ├── api.go # Go API (facade)
|
│ ├── api.go # Go API (facade)
|
||||||
│ ├── process.go # Yao Process: robot.*
|
│ ├── process.go # Yao Process: robot.*
|
||||||
│ └── jsapi.go # JS API: $robot.*
|
│ └── jsapi.go # JS API: robot (global) + Robot (class)
|
||||||
│
|
│
|
||||||
├── types/ # Types only (no logic, no external deps)
|
├── types/ # Types only (no logic, no external deps)
|
||||||
│ ├── enums.go # Phase, ClockMode, TriggerType, etc.
|
│ ├── enums.go # Phase, ClockMode, TriggerType, etc.
|
||||||
|
|
@ -246,12 +246,12 @@ type RobotState struct {
|
||||||
MemberID string `json:"member_id"`
|
MemberID string `json:"member_id"`
|
||||||
TeamID string `json:"team_id"`
|
TeamID string `json:"team_id"`
|
||||||
DisplayName string `json:"display_name"`
|
DisplayName string `json:"display_name"`
|
||||||
Status string `json:"status"` // idle | working | paused | error
|
Status string `json:"status"` // idle | working | paused | error
|
||||||
Running int `json:"running"` // current running count
|
Running int `json:"running"` // current running execution count
|
||||||
MaxRunning int `json:"max_running"` // max concurrent allowed
|
MaxRunning int `json:"max_running"` // max concurrent allowed (from Quota.Max)
|
||||||
LastRun *time.Time `json:"last_run,omitempty"`
|
LastRun *time.Time `json:"last_run,omitempty"`
|
||||||
NextRun *time.Time `json:"next_run,omitempty"`
|
NextRun *time.Time `json:"next_run,omitempty"`
|
||||||
CurrentExec string `json:"current_exec,omitempty"` // current execution ID
|
RunningIDs []string `json:"running_ids,omitempty"` // list of running execution IDs
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== Trigger Types ====================
|
// ==================== Trigger Types ====================
|
||||||
|
|
@ -437,21 +437,32 @@ func RobotNew(ctx *v8go.Context, memberID string) (*v8go.Value, error) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Static methods (Robot.List, Robot.Create):**
|
**Global object `robot` (static methods):**
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Register static methods on Robot constructor
|
func init() {
|
||||||
func RegisterStaticMethods(iso *v8go.Isolate, robotFn *v8go.FunctionTemplate) {
|
// Register global robot object (lowercase, for static methods)
|
||||||
robotFn.Set("List", v8go.NewFunctionTemplate(iso, jsListRobots))
|
v8.RegisterObject("robot", ExportObject)
|
||||||
robotFn.Set("Create", v8go.NewFunctionTemplate(iso, jsCreateRobot))
|
}
|
||||||
robotFn.Set("Get", v8go.NewFunctionTemplate(iso, jsGetRobot))
|
|
||||||
robotFn.Set("Execution", v8go.NewFunctionTemplate(iso, jsGetExecution))
|
// ExportObject exports the robot global object
|
||||||
|
func ExportObject(iso *v8go.Isolate) *v8go.ObjectTemplate {
|
||||||
|
obj := v8go.NewObjectTemplate(iso)
|
||||||
|
obj.Set("List", v8go.NewFunctionTemplate(iso, jsList))
|
||||||
|
obj.Set("Get", v8go.NewFunctionTemplate(iso, jsGet))
|
||||||
|
obj.Set("Create", v8go.NewFunctionTemplate(iso, jsCreate))
|
||||||
|
obj.Set("Update", v8go.NewFunctionTemplate(iso, jsUpdate))
|
||||||
|
obj.Set("Remove", v8go.NewFunctionTemplate(iso, jsRemove))
|
||||||
|
obj.Set("Execution", v8go.NewFunctionTemplate(iso, jsExecution))
|
||||||
|
return obj
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**TypeScript Interface:**
|
**TypeScript Interface:**
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
|
// ==================== Types ====================
|
||||||
|
|
||||||
interface RobotData {
|
interface RobotData {
|
||||||
member_id: string;
|
member_id: string;
|
||||||
team_id: string;
|
team_id: string;
|
||||||
|
|
@ -462,12 +473,14 @@ interface RobotData {
|
||||||
|
|
||||||
interface RobotState {
|
interface RobotState {
|
||||||
member_id: string;
|
member_id: string;
|
||||||
status: string;
|
team_id: string;
|
||||||
running: number;
|
display_name: string;
|
||||||
max_running: number;
|
status: string; // idle | working | paused | error
|
||||||
|
running: number; // current running execution count
|
||||||
|
max_running: number; // max concurrent allowed
|
||||||
last_run?: string;
|
last_run?: string;
|
||||||
next_run?: string;
|
next_run?: string;
|
||||||
current_exec?: string;
|
running_ids?: string[]; // list of running execution IDs
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TriggerResult {
|
interface TriggerResult {
|
||||||
|
|
@ -536,10 +549,29 @@ interface UpdateRequest {
|
||||||
robot_config?: RobotConfig;
|
robot_config?: RobotConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Robot instance (created via new Robot(memberID))
|
// ==================== Global object: robot ====================
|
||||||
|
// Static methods, no instance needed
|
||||||
|
|
||||||
|
interface RobotStatic {
|
||||||
|
List(query?: ListQuery): ListResult;
|
||||||
|
Get(memberID: string): RobotData;
|
||||||
|
Create(teamID: string, data: CreateRequest): RobotData;
|
||||||
|
Update(memberID: string, data: UpdateRequest): RobotData;
|
||||||
|
Remove(memberID: string): void;
|
||||||
|
Execution(execID: string): Execution;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare const robot: RobotStatic;
|
||||||
|
|
||||||
|
// ==================== Constructor: Robot ====================
|
||||||
|
// Instance methods, operate on specific robot
|
||||||
|
|
||||||
declare class Robot {
|
declare class Robot {
|
||||||
constructor(memberID: string);
|
constructor(memberID: string);
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
readonly memberID: string;
|
||||||
|
|
||||||
// Instance methods
|
// Instance methods
|
||||||
Status(): RobotState;
|
Status(): RobotState;
|
||||||
UpdateStatus(status: string): void;
|
UpdateStatus(status: string): void;
|
||||||
|
|
@ -548,69 +580,71 @@ declare class Robot {
|
||||||
Pause(execID: string): void;
|
Pause(execID: string): void;
|
||||||
Resume(execID: string): void;
|
Resume(execID: string): void;
|
||||||
Stop(execID: string): void;
|
Stop(execID: string): void;
|
||||||
|
|
||||||
// Static methods
|
|
||||||
static List(query?: ListQuery): ListResult;
|
|
||||||
static Create(teamID: string, data: CreateRequest): RobotData;
|
|
||||||
static Get(memberID: string): RobotData;
|
|
||||||
static Execution(execID: string): Execution;
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Usage:**
|
**Usage:**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// Create robot instance
|
// ==================== Global object: robot ====================
|
||||||
const robot = new Robot("mem_abc123");
|
// For CRUD and queries (no instance needed)
|
||||||
|
|
||||||
|
const list = robot.List({ team_id: "team_xyz", status: "idle" });
|
||||||
|
const data = robot.Get("mem_abc123");
|
||||||
|
const newRobot = robot.Create("team_xyz", {
|
||||||
|
display_name: "Sales Bot",
|
||||||
|
robot_config: { ... }
|
||||||
|
});
|
||||||
|
robot.Update("mem_abc123", { display_name: "Updated Bot" });
|
||||||
|
robot.Remove("mem_abc123");
|
||||||
|
const exec = robot.Execution("exec_456");
|
||||||
|
|
||||||
|
// ==================== Constructor: Robot ====================
|
||||||
|
// For operating on a specific robot instance
|
||||||
|
|
||||||
|
const bot = new Robot("mem_abc123");
|
||||||
|
|
||||||
// Instance methods
|
// Instance methods
|
||||||
const state = robot.Status();
|
const state = bot.Status();
|
||||||
if (state.status === "idle") {
|
if (state.status === "idle") {
|
||||||
// Trigger with human intervention
|
const result = bot.Trigger({
|
||||||
const result = robot.Trigger({
|
|
||||||
type: "human",
|
type: "human",
|
||||||
action: "task.add",
|
action: "task.add",
|
||||||
description: "Analyze sales data",
|
description: "Analyze sales data",
|
||||||
insert_at: "first", // urgent task, insert at beginning
|
insert_at: "first",
|
||||||
});
|
});
|
||||||
console.log("Triggered:", result.accepted);
|
console.log("Triggered:", result.accepted);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get execution history
|
// Get execution history for this robot
|
||||||
const execs = robot.Executions({ status: "completed", page: 1 });
|
const execs = bot.Executions({ status: "completed", page: 1 });
|
||||||
|
|
||||||
// Control execution
|
// Control execution
|
||||||
robot.Pause("exec_123");
|
bot.Pause("exec_123");
|
||||||
robot.Resume("exec_123");
|
bot.Resume("exec_123");
|
||||||
robot.Stop("exec_123");
|
bot.Stop("exec_123");
|
||||||
|
|
||||||
// Static methods
|
// Update status
|
||||||
const list = Robot.List({ team_id: "team_xyz", status: "idle" });
|
bot.UpdateStatus("paused");
|
||||||
const data = Robot.Get("mem_abc123");
|
|
||||||
const newRobot = Robot.Create("team_xyz", {
|
|
||||||
display_name: "Sales Bot",
|
|
||||||
robot_config: { ... }
|
|
||||||
});
|
|
||||||
const exec = Robot.Execution("exec_456");
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Usage in Agent Hooks:**
|
**Usage in Agent Hooks:**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
function Create(ctx, messages) {
|
function Create(ctx, messages) {
|
||||||
const robot = new Robot("mem_abc123");
|
const bot = new Robot("mem_abc123");
|
||||||
const state = robot.Status();
|
const state = bot.Status();
|
||||||
|
|
||||||
if (state.status === "working") {
|
if (state.status === "working") {
|
||||||
ctx.Send({ type: "text", props: { content: "Robot is busy" } });
|
ctx.Send({ type: "text", props: { content: "Robot is busy" } });
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = robot.Trigger({
|
const result = bot.Trigger({
|
||||||
type: "human",
|
type: "human",
|
||||||
action: "task.add",
|
action: "task.add",
|
||||||
description: "Analyze this data",
|
description: "Analyze this data",
|
||||||
insert_at: "first", // urgent: insert at beginning
|
insert_at: "first",
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result.accepted) {
|
if (result.accepted) {
|
||||||
|
|
@ -623,7 +657,7 @@ function Create(ctx, messages) {
|
||||||
function Next(ctx, payload) {
|
function Next(ctx, payload) {
|
||||||
const execID = ctx.memory.context.Get("robot_exec_id");
|
const execID = ctx.memory.context.Get("robot_exec_id");
|
||||||
if (execID) {
|
if (execID) {
|
||||||
const exec = Robot.Execution(execID);
|
const exec = robot.Execution(execID); // use global object
|
||||||
if (exec.status === "completed") {
|
if (exec.status === "completed") {
|
||||||
ctx.Send({
|
ctx.Send({
|
||||||
type: "text",
|
type: "text",
|
||||||
|
|
@ -1046,7 +1080,9 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Robot - runtime representation of an autonomous robot
|
// Robot - runtime representation of an autonomous robot (from __yao.member)
|
||||||
|
// Relationship: 1 Robot : N Executions (concurrent)
|
||||||
|
// Each trigger creates a new Execution (mapped to job.Job)
|
||||||
type Robot struct {
|
type Robot struct {
|
||||||
// From __yao.member
|
// From __yao.member
|
||||||
MemberID string `json:"member_id"`
|
MemberID string `json:"member_id"`
|
||||||
|
|
@ -1056,49 +1092,76 @@ type Robot struct {
|
||||||
Status RobotStatus `json:"robot_status"`
|
Status RobotStatus `json:"robot_status"`
|
||||||
AutonomousMode bool `json:"autonomous_mode"`
|
AutonomousMode bool `json:"autonomous_mode"`
|
||||||
|
|
||||||
// Parsed config
|
// Parsed config (from robot_config JSON field)
|
||||||
Config *Config `json:"-"`
|
Config *Config `json:"-"`
|
||||||
|
|
||||||
// Runtime state (job.Job stored as interface{} to avoid import cycle)
|
// Runtime state
|
||||||
Job interface{} `json:"-"` // *job.Job, set by manager
|
LastRun time.Time `json:"-"` // last execution start time
|
||||||
JobID string `json:"-"` // job_id for quick access
|
NextRun time.Time `json:"-"` // next scheduled execution (for clock trigger)
|
||||||
LastExecution time.Time `json:"-"`
|
|
||||||
NextExecution time.Time `json:"-"`
|
|
||||||
|
|
||||||
// Concurrency control
|
// Concurrency control
|
||||||
running int
|
// Each Robot can run multiple Executions concurrently (up to Quota.Max)
|
||||||
runningMu sync.Mutex
|
executions map[string]*Execution // execID -> Execution
|
||||||
|
execMu sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanRun checks if robot can accept new execution
|
// CanRun checks if robot can accept new execution
|
||||||
func (r *Robot) CanRun() bool {
|
func (r *Robot) CanRun() bool {
|
||||||
r.runningMu.Lock()
|
r.execMu.RLock()
|
||||||
defer r.runningMu.Unlock()
|
defer r.execMu.RUnlock()
|
||||||
return r.running < r.Config.Quota.GetMax()
|
return len(r.executions) < r.Config.Quota.GetMax()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IncrRunning increments running count
|
// RunningCount returns current running execution count
|
||||||
func (r *Robot) IncrRunning() {
|
func (r *Robot) RunningCount() int {
|
||||||
r.runningMu.Lock()
|
r.execMu.RLock()
|
||||||
defer r.runningMu.Unlock()
|
defer r.execMu.RUnlock()
|
||||||
r.running++
|
return len(r.executions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecrRunning decrements running count
|
// AddExecution adds an execution to tracking
|
||||||
func (r *Robot) DecrRunning() {
|
func (r *Robot) AddExecution(exec *Execution) {
|
||||||
r.runningMu.Lock()
|
r.execMu.Lock()
|
||||||
defer r.runningMu.Unlock()
|
defer r.execMu.Unlock()
|
||||||
if r.running > 0 {
|
if r.executions == nil {
|
||||||
r.running--
|
r.executions = make(map[string]*Execution)
|
||||||
}
|
}
|
||||||
|
r.executions[exec.ID] = exec
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execution - single execution context
|
// RemoveExecution removes an execution from tracking
|
||||||
|
func (r *Robot) RemoveExecution(execID string) {
|
||||||
|
r.execMu.Lock()
|
||||||
|
defer r.execMu.Unlock()
|
||||||
|
delete(r.executions, execID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetExecution returns an execution by ID
|
||||||
|
func (r *Robot) GetExecution(execID string) *Execution {
|
||||||
|
r.execMu.RLock()
|
||||||
|
defer r.execMu.RUnlock()
|
||||||
|
return r.executions[execID]
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetExecutions returns all running executions
|
||||||
|
func (r *Robot) GetExecutions() []*Execution {
|
||||||
|
r.execMu.RLock()
|
||||||
|
defer r.execMu.RUnlock()
|
||||||
|
execs := make([]*Execution, 0, len(r.executions))
|
||||||
|
for _, exec := range r.executions {
|
||||||
|
execs = append(execs, exec)
|
||||||
|
}
|
||||||
|
return execs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execution - single execution instance
|
||||||
|
// Each trigger creates a new Execution, mapped to a job.Job for monitoring
|
||||||
|
// Relationship: 1 Execution = 1 job.Job
|
||||||
type Execution struct {
|
type Execution struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"` // unique execution ID
|
||||||
MemberID string `json:"member_id"`
|
MemberID string `json:"member_id"` // robot member ID
|
||||||
TeamID string `json:"team_id"`
|
TeamID string `json:"team_id"`
|
||||||
TriggerType TriggerType `json:"trigger_type"`
|
TriggerType TriggerType `json:"trigger_type"` // clock | human | event
|
||||||
TriggerData interface{} `json:"trigger_data,omitempty"`
|
TriggerData interface{} `json:"trigger_data,omitempty"`
|
||||||
StartTime time.Time `json:"start_time"`
|
StartTime time.Time `json:"start_time"`
|
||||||
EndTime *time.Time `json:"end_time,omitempty"`
|
EndTime *time.Time `json:"end_time,omitempty"`
|
||||||
|
|
@ -1106,19 +1169,22 @@ type Execution struct {
|
||||||
Phase Phase `json:"phase"`
|
Phase Phase `json:"phase"`
|
||||||
Error string `json:"error,omitempty"`
|
Error string `json:"error,omitempty"`
|
||||||
|
|
||||||
|
// Job integration (each Execution = 1 job.Job)
|
||||||
|
JobID string `json:"job_id"` // corresponding job.Job ID
|
||||||
|
|
||||||
// Phase outputs
|
// Phase outputs
|
||||||
Inspiration *InspirationReport `json:"inspiration,omitempty"`
|
Inspiration *InspirationReport `json:"inspiration,omitempty"`
|
||||||
Goals []Goal `json:"goals,omitempty"` // all goals
|
Goals []Goal `json:"goals,omitempty"` // all goals
|
||||||
Tasks []Task `json:"tasks,omitempty"` // all tasks
|
Tasks []Task `json:"tasks,omitempty"` // all tasks
|
||||||
Current *CurrentState `json:"current,omitempty"` // current executing state
|
Current *CurrentState `json:"current,omitempty"` // current executing state
|
||||||
Results []TaskResult `json:"results,omitempty"`
|
Results []TaskResult `json:"results,omitempty"`
|
||||||
Delivery *DeliveryResult `json:"delivery,omitempty"`
|
Delivery *DeliveryResult `json:"delivery,omitempty"`
|
||||||
Learning []LearningEntry `json:"learning,omitempty"`
|
Learning []LearningEntry `json:"learning,omitempty"`
|
||||||
|
|
||||||
// Context
|
// Runtime (internal, not serialized)
|
||||||
ctx context.Context
|
ctx context.Context `json:"-"`
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc `json:"-"`
|
||||||
robot *Robot
|
robot *Robot `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentState - current executing goal and task
|
// CurrentState - current executing goal and task
|
||||||
|
|
@ -1377,10 +1443,11 @@ type RobotState struct {
|
||||||
TeamID string `json:"team_id"`
|
TeamID string `json:"team_id"`
|
||||||
DisplayName string `json:"display_name"`
|
DisplayName string `json:"display_name"`
|
||||||
Status RobotStatus `json:"status"`
|
Status RobotStatus `json:"status"`
|
||||||
|
Running int `json:"running"` // current running execution count
|
||||||
|
MaxRunning int `json:"max_running"` // max concurrent allowed
|
||||||
LastRun *time.Time `json:"last_run,omitempty"`
|
LastRun *time.Time `json:"last_run,omitempty"`
|
||||||
NextRun *time.Time `json:"next_run,omitempty"`
|
NextRun *time.Time `json:"next_run,omitempty"`
|
||||||
RunningID string `json:"running_id,omitempty"` // current execution ID
|
RunningIDs []string `json:"running_ids,omitempty"` // list of running execution IDs
|
||||||
RunningCnt int `json:"running_cnt"` // current running count
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue