aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2026-03-06 11:56:10 +0000
committerAleksandr Nogikh <nogikh@google.com>2026-03-10 09:38:24 +0000
commit048e3f22d8e073a5b47b0a4bc2704d7eccd04abd (patch)
treed2929778e285c0705f079e99621eec6b791d9b63
parent6972f30219093b03bcc1a54487e12a7097245c01 (diff)
dashboard/app: remember syz-agent names
For now, use a dashboard client name. In a prod deployment, that would be a persistent name of the machine where the syz-agent is hosted. This information be used later for restarting the aborted jobs.
-rw-r--r--dashboard/app/ai.go2
-rw-r--r--dashboard/app/ai_test.go4
-rw-r--r--dashboard/app/aidb/crud.go1
-rw-r--r--dashboard/app/aidb/entities.go1
-rw-r--r--dashboard/app/aidb/migrations/7_add_agent_name.down.sql1
-rw-r--r--dashboard/app/aidb/migrations/7_add_agent_name.up.sql1
-rw-r--r--dashboard/app/local_ui_test.go1
-rw-r--r--dashboard/app/templates/ai_job.html4
-rw-r--r--dashboard/dashapi/ai.go1
-rw-r--r--syz-agent/agent.go2
10 files changed, 18 insertions, 0 deletions
diff --git a/dashboard/app/ai.go b/dashboard/app/ai.go
index 13f6f24db..4f3c13fe5 100644
--- a/dashboard/app/ai.go
+++ b/dashboard/app/ai.go
@@ -56,6 +56,7 @@ type uiAIJob struct {
Workflow string
Description string
DescriptionLink string
+ AgentName string
Created time.Time
Started time.Time
Finished time.Time
@@ -302,6 +303,7 @@ func makeUIAIJob(job *aidb.Job) *uiAIJob {
Workflow: job.Workflow,
Description: job.Description,
DescriptionLink: job.Link,
+ AgentName: nullString(job.AgentName),
Created: job.Created,
Started: nullTime(job.Started),
Finished: nullTime(job.Finished),
diff --git a/dashboard/app/ai_test.go b/dashboard/app/ai_test.go
index 5802274da..fed84c9ba 100644
--- a/dashboard/app/ai_test.go
+++ b/dashboard/app/ai_test.go
@@ -70,6 +70,7 @@ func TestAIBugWorkflows(t *testing.T) {
requireWorkflows(kasanBug, nil)
_, err := c.agentClient.AIJobPoll(&dashapi.AIJobPollReq{
+ AgentName: "agent-test-bug-workflow",
CodeRevision: prog.GitRevision,
Workflows: []dashapi.AIWorkflow{
{Type: "patching", Name: "patching"},
@@ -198,6 +199,7 @@ func TestAIJob(t *testing.T) {
c.aiClient.pollEmailBug()
resp, err := c.agentClient.AIJobPoll(&dashapi.AIJobPollReq{
+ AgentName: "agent-test-job",
CodeRevision: prog.GitRevision,
Workflows: []dashapi.AIWorkflow{
{Type: "assessment-kcsan", Name: "assessment-kcsan"},
@@ -342,6 +344,7 @@ func TestAIAssessmentKCSAN(t *testing.T) {
extID := c.aiClient.pollEmailExtID()
resp, err := c.agentClient.AIJobPoll(&dashapi.AIJobPollReq{
+ AgentName: "agent-test-assessment",
CodeRevision: prog.GitRevision,
Workflows: []dashapi.AIWorkflow{
{Type: ai.WorkflowAssessmentKCSAN, Name: string(ai.WorkflowAssessmentKCSAN)},
@@ -482,6 +485,7 @@ func TestAIJobAutoCreate(t *testing.T) {
c.aiClient.pollEmailExtID()
pollReq := &dashapi.AIJobPollReq{
+ AgentName: "agent-test-auto-create",
CodeRevision: prog.GitRevision,
Workflows: []dashapi.AIWorkflow{
{Type: ai.WorkflowAssessmentKCSAN, Name: string(ai.WorkflowAssessmentKCSAN)},
diff --git a/dashboard/app/aidb/crud.go b/dashboard/app/aidb/crud.go
index 6ed1c611a..4e90db351 100644
--- a/dashboard/app/aidb/crud.go
+++ b/dashboard/app/aidb/crud.go
@@ -129,6 +129,7 @@ func StartJob(ctx context.Context, req *dashapi.AIJobPollReq) (*Job, error) {
}
job.Started = spanner.NullTime{Time: TimeNow(ctx), Valid: true}
job.CodeRevision = req.CodeRevision
+ job.AgentName = toNullString(req.AgentName)
mut, err := spanner.InsertOrUpdateStruct("Jobs", job)
if err != nil {
return err
diff --git a/dashboard/app/aidb/entities.go b/dashboard/app/aidb/entities.go
index f256cdda6..7b6edd222 100644
--- a/dashboard/app/aidb/entities.go
+++ b/dashboard/app/aidb/entities.go
@@ -38,6 +38,7 @@ type Job struct {
Finished spanner.NullTime
CodeRevision string // syzkaller revision, filled when the job is started
Error string // for finished jobs
+ AgentName spanner.NullString
Args spanner.NullJSON
Results spanner.NullJSON
Correct spanner.NullBool
diff --git a/dashboard/app/aidb/migrations/7_add_agent_name.down.sql b/dashboard/app/aidb/migrations/7_add_agent_name.down.sql
new file mode 100644
index 000000000..f512f1166
--- /dev/null
+++ b/dashboard/app/aidb/migrations/7_add_agent_name.down.sql
@@ -0,0 +1 @@
+ALTER TABLE Jobs DROP COLUMN AgentName;
diff --git a/dashboard/app/aidb/migrations/7_add_agent_name.up.sql b/dashboard/app/aidb/migrations/7_add_agent_name.up.sql
new file mode 100644
index 000000000..117a97a46
--- /dev/null
+++ b/dashboard/app/aidb/migrations/7_add_agent_name.up.sql
@@ -0,0 +1 @@
+ALTER TABLE Jobs ADD COLUMN AgentName STRING(512);
diff --git a/dashboard/app/local_ui_test.go b/dashboard/app/local_ui_test.go
index 9a2900489..f1d10ea5e 100644
--- a/dashboard/app/local_ui_test.go
+++ b/dashboard/app/local_ui_test.go
@@ -284,6 +284,7 @@ func populateLocalUIDB(t *testing.T, c *Ctx) {
}
t.Logf("done populating DB")
resp, _ := globalClient.AIJobPoll(&dashapi.AIJobPollReq{
+ AgentName: "agent-local-ui",
CodeRevision: "xxx",
Workflows: []dashapi.AIWorkflow{
{Type: ai.WorkflowPatching, Name: string(ai.WorkflowPatching)},
diff --git a/dashboard/app/templates/ai_job.html b/dashboard/app/templates/ai_job.html
index 2ff4ce975..21ef1fdd3 100644
--- a/dashboard/app/templates/ai_job.html
+++ b/dashboard/app/templates/ai_job.html
@@ -153,6 +153,10 @@ Detailed info on a single AI job execution.
{{template "header" .Header}}
{{template "ai_job_list" .Jobs}}
+ {{if .Job.AgentName}}
+ <b>Agent:</b> {{.Job.AgentName}}<br><br>
+ {{end}}
+
{{if .Header.AIActions}}
{{if and (ne .Job.Correct "⏳") (ne .Job.Correct "💥")}}
<form method="POST">
diff --git a/dashboard/dashapi/ai.go b/dashboard/dashapi/ai.go
index dfa410402..a0ac7739c 100644
--- a/dashboard/dashapi/ai.go
+++ b/dashboard/dashapi/ai.go
@@ -9,6 +9,7 @@ import (
)
type AIJobPollReq struct {
+ AgentName string
CodeRevision string // git commit of the syz-agent server
Workflows []AIWorkflow
}
diff --git a/syz-agent/agent.go b/syz-agent/agent.go
index 5d398cced..6ef2669d4 100644
--- a/syz-agent/agent.go
+++ b/syz-agent/agent.go
@@ -212,7 +212,9 @@ type Server struct {
func (s *Server) poll(ctx context.Context) (bool, error) {
s.resetModelQuota()
+ agentName := s.cfg.DashboardClient
req := &dashapi.AIJobPollReq{
+ AgentName: agentName,
CodeRevision: prog.GitRevision,
}
for _, flow := range aflow.Flows {