Skip to content

Commit ffe57a7

Browse files
fix: send each worker's actor status instead of joining it in the page
The workers bar coloured its segments from the loaded actor page, so searching, sorting or paging the *actors* table recoloured the *workers* one — a pod whose actor fell off the page read as `Not loaded`, a status no cluster reports. The controller has both whole lists when it builds the response, so it carries the status on the worker entry and the page joins nothing. Also from review: - Every actor is offered to the join, not only those the atespace scope kept. A worker running an actor whose template lives elsewhere reported itself idle. - A live actor on a shared pod wins over a parked one; the lowest id breaks ties. - A failed read no longer renders as "No actors in this scope", and the legend stays when a scope empties so the table beneath it does not jump. - The per-actor ceiling is 80, which is the widest row that fits the card. - An extension's PNG favicon is no longer served under an SVG type, and the created link carries the marker so a second call retargets it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Nicholas Bucher <behappy54321@gmail.com>
1 parent e848172 commit ffe57a7

13 files changed

Lines changed: 137 additions & 42 deletions

File tree

go/api/gen/kagent/api/v1alpha1/system.pb.go

Lines changed: 15 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go/core/internal/grpcserver/system.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ func (s *systemServer) GetSubstrateStatus(ctx context.Context, request *apiv1alp
112112
ActorNamespace: worker.ActorNamespace,
113113
ActorTemplate: worker.ActorTemplate,
114114
ActorId: worker.ActorID,
115+
ActorStatus: worker.ActorStatus,
115116
Ip: worker.IP,
116117
Version: worker.Version,
117118
})

go/core/internal/service/system/service.go

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ type SubstrateWorker struct {
101101
ActorNamespace string
102102
ActorTemplate string
103103
ActorID string
104+
ActorStatus string
104105
IP string
105106
Version int64
106107
}
@@ -374,14 +375,20 @@ func (s *Service) listATEState(ctx context.Context, namespaces []string) ([]Subs
374375
}
375376

376377
actors := make([]SubstrateActor, 0, len(actorsFromAPI))
378+
// Every actor, scope or no scope. The workers below are filtered by *their* namespace
379+
// and an actor by its template's, so a worker running an actor whose template lives
380+
// elsewhere finds no match in the scoped list and reports itself idle.
381+
placed := make([]SubstrateActor, 0, len(actorsFromAPI))
377382
for _, actor := range actorsFromAPI {
378383
if actor == nil {
379384
continue
380385
}
386+
converted := actorFromProto(actor)
387+
placed = append(placed, converted)
381388
if !allowedAtespace(actor.GetActorTemplate().GetAtespace(), allowAll, allowed) {
382389
continue
383390
}
384-
actors = append(actors, actorFromProto(actor))
391+
actors = append(actors, converted)
385392
}
386393

387394
workers := make([]SubstrateWorker, 0, len(workersFromAPI))
@@ -397,7 +404,7 @@ func (s *Service) listATEState(ctx context.Context, namespaces []string) ([]Subs
397404
}
398405
workers = append(workers, workerFromProto(worker))
399406
}
400-
placeActorsOnWorkers(workers, actors)
407+
placeActorsOnWorkers(workers, placed)
401408
return templates, actors, workers, nil
402409
}
403410

@@ -443,8 +450,26 @@ func workerFromProto(worker *ateapipb.Worker) SubstrateWorker {
443450
// the one place both whole lists are in hand to join them.
444451
//
445452
// A worker holds several actors since v0.0.25 and `SubstrateWorker` has room for one, so
446-
// the lowest actor id wins. Lowest rather than first seen: ate-api returns actors
447-
// unordered, so by arrival the cell would name a different actor on each poll.
453+
// a live actor wins over a parked one and the lowest id breaks the tie. Never first seen:
454+
// ate-api returns actors unordered, so the cell would name a different actor on each poll.
455+
// supersedes reports whether one actor on a pod should be named over another: a running
456+
// one over a parked one, and otherwise the lower id, so the answer does not depend on the
457+
// order ate-api happened to return them in.
458+
func supersedes(candidate, held SubstrateActor) bool {
459+
if parkedActor(candidate) != parkedActor(held) {
460+
return parkedActor(held)
461+
}
462+
return candidate.ActorID < held.ActorID
463+
}
464+
465+
func parkedActor(actor SubstrateActor) bool {
466+
switch actor.Status {
467+
case "Suspended", "Paused", "Unknown", "":
468+
return true
469+
}
470+
return false
471+
}
472+
448473
func placeActorsOnWorkers(workers []SubstrateWorker, actors []SubstrateActor) {
449474
type pod struct{ namespace, name string }
450475
holding := make(map[pod]SubstrateActor, len(actors))
@@ -453,7 +478,7 @@ func placeActorsOnWorkers(workers []SubstrateWorker, actors []SubstrateActor) {
453478
continue
454479
}
455480
key := pod{actor.AteomPodNamespace, actor.AteomPodName}
456-
if held, ok := holding[key]; ok && held.ActorID <= actor.ActorID {
481+
if held, ok := holding[key]; ok && !supersedes(actor, held) {
457482
continue
458483
}
459484
holding[key] = actor
@@ -466,6 +491,7 @@ func placeActorsOnWorkers(workers []SubstrateWorker, actors []SubstrateActor) {
466491
workers[i].ActorNamespace = actor.ActorTemplateNamespace
467492
workers[i].ActorTemplate = actor.ActorTemplateName
468493
workers[i].ActorID = actor.ActorID
494+
workers[i].ActorStatus = actor.Status
469495
}
470496
}
471497

go/core/internal/service/system/service_test.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,9 @@ func TestGetSubstrateStatus(t *testing.T) {
164164
Metadata: &ateapipb.ResourceMetadata{Name: "actor-1"},
165165
ActorTemplate: &ateapipb.ObjectRef{Atespace: "team", Name: "template"},
166166
Status: &ateapipb.ActorStatus{
167-
State: ateapipb.ActorState_ACTOR_STATE_RUNNING,
167+
// Parked, and the lower id: the pod must still be reported as running
168+
// actor-2, because a suspended actor says nothing about a busy pod.
169+
State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED,
168170
// Where this actor is placed. `ateapi.Worker` carries no actor
169171
// reference, so this is the only record of the binding.
170172
WorkerAssignment: &ateapipb.WorkerAssignment{
@@ -200,13 +202,20 @@ func TestGetSubstrateStatus(t *testing.T) {
200202
assert.Equal(t, "kagent", result.ActorTemplates[0].HarnessName)
201203
assert.True(t, result.ActorTemplates[0].ManagedByKagent)
202204
require.Len(t, result.Actors, 2)
203-
assert.Equal(t, "Running", result.Actors[0].Status)
205+
// By status rather than by position: the fixture now holds one of each, and an
206+
// index here would assert the sort order under the guise of asserting the label.
207+
actorStatuses := map[string]string{}
208+
for _, actor := range result.Actors {
209+
actorStatuses[actor.ActorID] = actor.Status
210+
}
211+
assert.Equal(t, map[string]string{"actor-1": "Suspended", "actor-2": "Running"}, actorStatuses)
204212
require.Len(t, result.Workers, 1)
205213
assert.Equal(t, "worker-0", result.Workers[0].WorkerPod)
206214
// The worker says what is on it. Read from the actor's own assignment, because
207215
// the worker message has no field for it — without the join every pod reports
208216
// holding nothing and a running fleet reads as an idle one.
209-
assert.Equal(t, "actor-1", result.Workers[0].ActorID)
217+
assert.Equal(t, "actor-2", result.Workers[0].ActorID)
218+
assert.Equal(t, "Running", result.Workers[0].ActorStatus)
210219
assert.Equal(t, "template", result.Workers[0].ActorTemplate)
211220
assert.Equal(t, "team", result.Workers[0].ActorNamespace)
212221
assert.Equal(t, int64(3), result.Workers[0].Version)

proto/kagent/api/v1alpha1/system.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,7 @@ message SubstrateWorker {
9494
string actor_id = 6;
9595
string ip = 7;
9696
int64 version = 8;
97+
// What the actor on this pod is doing, so a reader of the worker list is not
98+
// sent to the actor list to find out. Empty when the pod holds nothing.
99+
string actor_status = 9;
97100
}

ui/src/api/domain/substrate.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ export interface SubstrateWorkerEntry {
7373
actorNamespace?: string;
7474
actorTemplate?: string;
7575
actorId?: string;
76+
/** What the actor on this pod is doing. Absent when the pod holds nothing. */
77+
actorStatus?: string;
7678
ip?: string;
7779
version?: number;
7880
}

ui/src/api/grpc/operations.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,7 @@ function toWorkerEntry(worker: PbSubstrateWorker): SubstrateWorkerEntry {
11071107
actorNamespace: orUndefined(worker.actorNamespace),
11081108
actorTemplate: orUndefined(worker.actorTemplate),
11091109
actorId: orUndefined(worker.actorId),
1110+
actorStatus: orUndefined(worker.actorStatus),
11101111
ip: orUndefined(worker.ip),
11111112
version: toNumber(worker.version),
11121113
};

ui/src/appExtensions/appExtensions.test.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -458,10 +458,18 @@ describe("applyExtensionBranding", () => {
458458
document.head.innerHTML = "";
459459

460460
applyExtensionBranding({ faviconUrl: "/my-mark.svg" });
461+
// Twice: the link it creates carries the marker, so the second call retargets the
462+
// first rather than leaving two icons for the browser to choose between.
463+
applyExtensionBranding({ faviconUrl: "/other-mark.svg" });
461464

462-
expect(
463-
document.querySelector<HTMLLinkElement>('link[rel="icon"]')?.href,
464-
).toContain("/my-mark.svg");
465+
expect(document.querySelectorAll('link[rel="icon"]')).toHaveLength(1);
466+
expect(favicon()?.href).toContain("/other-mark.svg");
467+
});
468+
469+
it("does not advertise SVG for an icon that is not one", () => {
470+
applyExtensionBranding({ faviconUrl: "/my-mark.png" });
471+
472+
expect(favicon()?.getAttribute("type")).toBe("");
465473
});
466474
});
467475

ui/src/appExtensions/branding.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,17 @@ export function applyExtensionBranding(branding: ExtensionBranding | undefined):
5050
if (!branding?.faviconUrl) return;
5151

5252
// The tag `index.html` ships, or a fresh one if a host page dropped it — a missing
53-
// icon is not a reason to leave the extension's branding unapplied.
54-
const link =
55-
document.querySelector<HTMLLinkElement>("link[data-app-favicon]") ??
56-
document.head.appendChild(Object.assign(document.createElement("link"), { rel: "icon" }));
53+
// icon is not a reason to leave the extension's branding unapplied. The new one carries
54+
// the marker too, so a second call retargets this link instead of appending another.
55+
let link = document.querySelector<HTMLLinkElement>("link[data-app-favicon]");
56+
if (!link) {
57+
link = document.createElement("link");
58+
link.rel = "icon";
59+
link.dataset.appFavicon = "";
60+
document.head.appendChild(link);
61+
}
5762
link.href = branding.faviconUrl;
63+
// `index.html` declares SVG. Left alone, a PNG would be served under a type that says
64+
// otherwise, which browsers are entitled to act on when choosing between icons.
65+
link.type = branding.faviconUrl.endsWith(".svg") ? "image/svg+xml" : "";
5866
}

ui/src/generated/kagent/api/v1alpha1/system_pb.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import type { JsonObject, Message } from "@bufbuild/protobuf";
1111
* Describes the file kagent/api/v1alpha1/system.proto.
1212
*/
1313
export const file_kagent_api_v1alpha1_system: GenFile = /*@__PURE__*/
14-
fileDesc("CiBrYWdlbnQvYXBpL3YxYWxwaGExL3N5c3RlbS5wcm90bxITa2FnZW50LmFwaS52MWFscGhhMSITChFHZXRWZXJzaW9uUmVxdWVzdCJUChJHZXRWZXJzaW9uUmVzcG9uc2USFgoOa2FnZW50X3ZlcnNpb24YASABKAkSEgoKZ2l0X2NvbW1pdBgCIAEoCRISCgpidWlsZF9kYXRlGAMgASgJIhcKFUdldEN1cnJlbnRVc2VyUmVxdWVzdCJBChZHZXRDdXJyZW50VXNlclJlc3BvbnNlEicKBmNsYWltcxgBIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QiFwoVTGlzdE5hbWVzcGFjZXNSZXF1ZXN0IikKCU5hbWVzcGFjZRIMCgRuYW1lGAEgASgJEg4KBnN0YXR1cxgCIAEoCSJMChZMaXN0TmFtZXNwYWNlc1Jlc3BvbnNlEjIKCm5hbWVzcGFjZXMYASADKAsyHi5rYWdlbnQuYXBpLnYxYWxwaGExLk5hbWVzcGFjZSIuChlHZXRTdWJzdHJhdGVTdGF0dXNSZXF1ZXN0EhEKCW5hbWVzcGFjZRgBIAEoCSK2AgoaR2V0U3Vic3RyYXRlU3RhdHVzUmVzcG9uc2USDwoHZW5hYmxlZBgBIAEoCBIVCg1hdGVfYXBpX2Vycm9yGAIgASgJEj4KDHdvcmtlcl9wb29scxgDIAMoCzIoLmthZ2VudC5hcGkudjFhbHBoYTEuU3Vic3RyYXRlV29ya2VyUG9vbBJECg9hY3Rvcl90ZW1wbGF0ZXMYBCADKAsyKy5rYWdlbnQuYXBpLnYxYWxwaGExLlN1YnN0cmF0ZUFjdG9yVGVtcGxhdGUSMwoGYWN0b3JzGAUgAygLMiMua2FnZW50LmFwaS52MWFscGhhMS5TdWJzdHJhdGVBY3RvchI1Cgd3b3JrZXJzGAYgAygLMiQua2FnZW50LmFwaS52MWFscGhhMS5TdWJzdHJhdGVXb3JrZXIiXQoTU3Vic3RyYXRlV29ya2VyUG9vbBIRCgluYW1lc3BhY2UYASABKAkSDAoEbmFtZRgCIAEoCRIQCghyZXBsaWNhcxgDIAEoBRITCgthdGVvbV9pbWFnZRgEIAEoCSLbAQoWU3Vic3RyYXRlQWN0b3JUZW1wbGF0ZRIRCgluYW1lc3BhY2UYASABKAkSDAoEbmFtZRgCIAEoCRINCgVwaGFzZRgDIAEoCRIXCg9nb2xkZW5fYWN0b3JfaWQYBCABKAkSFwoPZ29sZGVuX3NuYXBzaG90GAUgASgJEhUKDXNhbmRib3hfY2xhc3MYBiABKAkSFwoPd29ya2VyX3NlbGVjdG9yGAcgASgJEhQKDGhhcm5lc3NfbmFtZRgIIAEoCRIZChFtYW5hZ2VkX2J5X2thZ2VudBgJIAEoCCKwAgoOU3Vic3RyYXRlQWN0b3ISEAoIYWN0b3JfaWQYASABKAkSEAoIYXRlc3BhY2UYAiABKAkSDgoGc3RhdHVzGAMgASgJEiAKGGFjdG9yX3RlbXBsYXRlX25hbWVzcGFjZRgEIAEoCRIbChNhY3Rvcl90ZW1wbGF0ZV9uYW1lGAUgASgJEhsKE2F0ZW9tX3BvZF9uYW1lc3BhY2UYBiABKAkSFgoOYXRlb21fcG9kX25hbWUYByABKAkSFAoMYXRlb21fcG9kX2lwGAggASgJEhcKD2xhdGVzdF9zbmFwc2hvdBgJIAEoCRIYChB3b3JrZXJfcG9vbF9uYW1lGAogASgJEhwKFGluX3Byb2dyZXNzX3NuYXBzaG90GAsgASgJEg8KB3ZlcnNpb24YDCABKAMitAEKD1N1YnN0cmF0ZVdvcmtlchIYChB3b3JrZXJfbmFtZXNwYWNlGAEgASgJEhMKC3dvcmtlcl9wb29sGAIgASgJEhIKCndvcmtlcl9wb2QYAyABKAkSFwoPYWN0b3JfbmFtZXNwYWNlGAQgASgJEhYKDmFjdG9yX3RlbXBsYXRlGAUgASgJEhAKCGFjdG9yX2lkGAYgASgJEgoKAmlwGAcgASgJEg8KB3ZlcnNpb24YCCABKAMyuwMKDVN5c3RlbVNlcnZpY2USXQoKR2V0VmVyc2lvbhImLmthZ2VudC5hcGkudjFhbHBoYTEuR2V0VmVyc2lvblJlcXVlc3QaJy5rYWdlbnQuYXBpLnYxYWxwaGExLkdldFZlcnNpb25SZXNwb25zZRJpCg5HZXRDdXJyZW50VXNlchIqLmthZ2VudC5hcGkudjFhbHBoYTEuR2V0Q3VycmVudFVzZXJSZXF1ZXN0Gisua2FnZW50LmFwaS52MWFscGhhMS5HZXRDdXJyZW50VXNlclJlc3BvbnNlEmkKDkxpc3ROYW1lc3BhY2VzEioua2FnZW50LmFwaS52MWFscGhhMS5MaXN0TmFtZXNwYWNlc1JlcXVlc3QaKy5rYWdlbnQuYXBpLnYxYWxwaGExLkxpc3ROYW1lc3BhY2VzUmVzcG9uc2USdQoSR2V0U3Vic3RyYXRlU3RhdHVzEi4ua2FnZW50LmFwaS52MWFscGhhMS5HZXRTdWJzdHJhdGVTdGF0dXNSZXF1ZXN0Gi8ua2FnZW50LmFwaS52MWFscGhhMS5HZXRTdWJzdHJhdGVTdGF0dXNSZXNwb25zZUJJWkdnaXRodWIuY29tL2thZ2VudC1kZXYva2FnZW50L2dvL2FwaS9nZW4va2FnZW50L2FwaS92MWFscGhhMTthcGl2MWFscGhhMWIGcHJvdG8z", [file_google_protobuf_struct]);
14+
fileDesc("CiBrYWdlbnQvYXBpL3YxYWxwaGExL3N5c3RlbS5wcm90bxITa2FnZW50LmFwaS52MWFscGhhMSITChFHZXRWZXJzaW9uUmVxdWVzdCJUChJHZXRWZXJzaW9uUmVzcG9uc2USFgoOa2FnZW50X3ZlcnNpb24YASABKAkSEgoKZ2l0X2NvbW1pdBgCIAEoCRISCgpidWlsZF9kYXRlGAMgASgJIhcKFUdldEN1cnJlbnRVc2VyUmVxdWVzdCJBChZHZXRDdXJyZW50VXNlclJlc3BvbnNlEicKBmNsYWltcxgBIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QiFwoVTGlzdE5hbWVzcGFjZXNSZXF1ZXN0IikKCU5hbWVzcGFjZRIMCgRuYW1lGAEgASgJEg4KBnN0YXR1cxgCIAEoCSJMChZMaXN0TmFtZXNwYWNlc1Jlc3BvbnNlEjIKCm5hbWVzcGFjZXMYASADKAsyHi5rYWdlbnQuYXBpLnYxYWxwaGExLk5hbWVzcGFjZSIuChlHZXRTdWJzdHJhdGVTdGF0dXNSZXF1ZXN0EhEKCW5hbWVzcGFjZRgBIAEoCSK2AgoaR2V0U3Vic3RyYXRlU3RhdHVzUmVzcG9uc2USDwoHZW5hYmxlZBgBIAEoCBIVCg1hdGVfYXBpX2Vycm9yGAIgASgJEj4KDHdvcmtlcl9wb29scxgDIAMoCzIoLmthZ2VudC5hcGkudjFhbHBoYTEuU3Vic3RyYXRlV29ya2VyUG9vbBJECg9hY3Rvcl90ZW1wbGF0ZXMYBCADKAsyKy5rYWdlbnQuYXBpLnYxYWxwaGExLlN1YnN0cmF0ZUFjdG9yVGVtcGxhdGUSMwoGYWN0b3JzGAUgAygLMiMua2FnZW50LmFwaS52MWFscGhhMS5TdWJzdHJhdGVBY3RvchI1Cgd3b3JrZXJzGAYgAygLMiQua2FnZW50LmFwaS52MWFscGhhMS5TdWJzdHJhdGVXb3JrZXIiXQoTU3Vic3RyYXRlV29ya2VyUG9vbBIRCgluYW1lc3BhY2UYASABKAkSDAoEbmFtZRgCIAEoCRIQCghyZXBsaWNhcxgDIAEoBRITCgthdGVvbV9pbWFnZRgEIAEoCSLbAQoWU3Vic3RyYXRlQWN0b3JUZW1wbGF0ZRIRCgluYW1lc3BhY2UYASABKAkSDAoEbmFtZRgCIAEoCRINCgVwaGFzZRgDIAEoCRIXCg9nb2xkZW5fYWN0b3JfaWQYBCABKAkSFwoPZ29sZGVuX3NuYXBzaG90GAUgASgJEhUKDXNhbmRib3hfY2xhc3MYBiABKAkSFwoPd29ya2VyX3NlbGVjdG9yGAcgASgJEhQKDGhhcm5lc3NfbmFtZRgIIAEoCRIZChFtYW5hZ2VkX2J5X2thZ2VudBgJIAEoCCKwAgoOU3Vic3RyYXRlQWN0b3ISEAoIYWN0b3JfaWQYASABKAkSEAoIYXRlc3BhY2UYAiABKAkSDgoGc3RhdHVzGAMgASgJEiAKGGFjdG9yX3RlbXBsYXRlX25hbWVzcGFjZRgEIAEoCRIbChNhY3Rvcl90ZW1wbGF0ZV9uYW1lGAUgASgJEhsKE2F0ZW9tX3BvZF9uYW1lc3BhY2UYBiABKAkSFgoOYXRlb21fcG9kX25hbWUYByABKAkSFAoMYXRlb21fcG9kX2lwGAggASgJEhcKD2xhdGVzdF9zbmFwc2hvdBgJIAEoCRIYChB3b3JrZXJfcG9vbF9uYW1lGAogASgJEhwKFGluX3Byb2dyZXNzX3NuYXBzaG90GAsgASgJEg8KB3ZlcnNpb24YDCABKAMiygEKD1N1YnN0cmF0ZVdvcmtlchIYChB3b3JrZXJfbmFtZXNwYWNlGAEgASgJEhMKC3dvcmtlcl9wb29sGAIgASgJEhIKCndvcmtlcl9wb2QYAyABKAkSFwoPYWN0b3JfbmFtZXNwYWNlGAQgASgJEhYKDmFjdG9yX3RlbXBsYXRlGAUgASgJEhAKCGFjdG9yX2lkGAYgASgJEgoKAmlwGAcgASgJEg8KB3ZlcnNpb24YCCABKAMSFAoMYWN0b3Jfc3RhdHVzGAkgASgJMrsDCg1TeXN0ZW1TZXJ2aWNlEl0KCkdldFZlcnNpb24SJi5rYWdlbnQuYXBpLnYxYWxwaGExLkdldFZlcnNpb25SZXF1ZXN0Gicua2FnZW50LmFwaS52MWFscGhhMS5HZXRWZXJzaW9uUmVzcG9uc2USaQoOR2V0Q3VycmVudFVzZXISKi5rYWdlbnQuYXBpLnYxYWxwaGExLkdldEN1cnJlbnRVc2VyUmVxdWVzdBorLmthZ2VudC5hcGkudjFhbHBoYTEuR2V0Q3VycmVudFVzZXJSZXNwb25zZRJpCg5MaXN0TmFtZXNwYWNlcxIqLmthZ2VudC5hcGkudjFhbHBoYTEuTGlzdE5hbWVzcGFjZXNSZXF1ZXN0Gisua2FnZW50LmFwaS52MWFscGhhMS5MaXN0TmFtZXNwYWNlc1Jlc3BvbnNlEnUKEkdldFN1YnN0cmF0ZVN0YXR1cxIuLmthZ2VudC5hcGkudjFhbHBoYTEuR2V0U3Vic3RyYXRlU3RhdHVzUmVxdWVzdBovLmthZ2VudC5hcGkudjFhbHBoYTEuR2V0U3Vic3RyYXRlU3RhdHVzUmVzcG9uc2VCSVpHZ2l0aHViLmNvbS9rYWdlbnQtZGV2L2thZ2VudC9nby9hcGkvZ2VuL2thZ2VudC9hcGkvdjFhbHBoYTE7YXBpdjFhbHBoYTFiBnByb3RvMw", [file_google_protobuf_struct]);
1515

1616
/**
1717
* @generated from message kagent.api.v1alpha1.GetVersionRequest
@@ -398,6 +398,14 @@ export type SubstrateWorker = Message<"kagent.api.v1alpha1.SubstrateWorker"> & {
398398
* @generated from field: int64 version = 8;
399399
*/
400400
version: bigint;
401+
402+
/**
403+
* What the actor on this pod is doing, so a reader of the worker list is not
404+
* sent to the actor list to find out. Empty when the pod holds nothing.
405+
*
406+
* @generated from field: string actor_status = 9;
407+
*/
408+
actorStatus: string;
401409
};
402410

403411
/**

0 commit comments

Comments
 (0)