@getpaseo/server 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server/client/daemon-client.d.ts +0 -10
- package/dist/server/client/daemon-client.d.ts.map +1 -1
- package/dist/server/client/daemon-client.js +1 -34
- package/dist/server/client/daemon-client.js.map +1 -1
- package/dist/server/server/session.d.ts +3 -1
- package/dist/server/server/session.d.ts.map +1 -1
- package/dist/server/server/session.js +117 -65
- package/dist/server/server/session.js.map +1 -1
- package/dist/server/shared/messages.d.ts +88 -209
- package/dist/server/shared/messages.d.ts.map +1 -1
- package/dist/server/shared/messages.js +13 -29
- package/dist/server/shared/messages.js.map +1 -1
- package/dist/server/terminal/terminal.d.ts +8 -0
- package/dist/server/terminal/terminal.d.ts.map +1 -1
- package/dist/server/terminal/terminal.js +59 -0
- package/dist/server/terminal/terminal.js.map +1 -1
- package/package.json +5 -5
|
@@ -582,14 +582,74 @@ export class Session {
|
|
|
582
582
|
}
|
|
583
583
|
}
|
|
584
584
|
}
|
|
585
|
-
matchesAgentFilter(
|
|
586
|
-
|
|
585
|
+
matchesAgentFilter(options) {
|
|
586
|
+
const { agent, project, filter } = options;
|
|
587
|
+
if (filter?.labels) {
|
|
588
|
+
const matchesLabels = Object.entries(filter.labels).every(([key, value]) => agent.labels[key] === value);
|
|
589
|
+
if (!matchesLabels) {
|
|
590
|
+
return false;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
const includeArchived = filter?.includeArchived ?? false;
|
|
594
|
+
if (!includeArchived && agent.archivedAt) {
|
|
587
595
|
return false;
|
|
588
596
|
}
|
|
589
|
-
if (
|
|
590
|
-
|
|
597
|
+
if (filter?.statuses && filter.statuses.length > 0) {
|
|
598
|
+
const statuses = new Set(filter.statuses);
|
|
599
|
+
if (!statuses.has(agent.status)) {
|
|
600
|
+
return false;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
if (typeof filter?.requiresAttention === "boolean") {
|
|
604
|
+
const requiresAttention = agent.requiresAttention ?? false;
|
|
605
|
+
if (requiresAttention !== filter.requiresAttention) {
|
|
606
|
+
return false;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
if (filter?.projectKeys && filter.projectKeys.length > 0) {
|
|
610
|
+
const projectKeys = new Set(filter.projectKeys.filter((item) => item.trim().length > 0));
|
|
611
|
+
if (projectKeys.size > 0 && !projectKeys.has(project.projectKey)) {
|
|
612
|
+
return false;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
return true;
|
|
616
|
+
}
|
|
617
|
+
getAgentUpdateTargetId(update) {
|
|
618
|
+
return update.kind === "remove" ? update.agentId : update.agent.id;
|
|
619
|
+
}
|
|
620
|
+
bufferOrEmitAgentUpdate(subscription, payload) {
|
|
621
|
+
if (subscription.isBootstrapping) {
|
|
622
|
+
subscription.pendingUpdatesByAgentId.set(this.getAgentUpdateTargetId(payload), payload);
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
this.emit({
|
|
626
|
+
type: "agent_update",
|
|
627
|
+
payload,
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
flushBootstrappedAgentUpdates(options) {
|
|
631
|
+
const subscription = this.agentUpdatesSubscription;
|
|
632
|
+
if (!subscription || !subscription.isBootstrapping) {
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
subscription.isBootstrapping = false;
|
|
636
|
+
const pending = Array.from(subscription.pendingUpdatesByAgentId.values());
|
|
637
|
+
subscription.pendingUpdatesByAgentId.clear();
|
|
638
|
+
for (const payload of pending) {
|
|
639
|
+
if (payload.kind === "upsert") {
|
|
640
|
+
const snapshotUpdatedAt = options?.snapshotUpdatedAtByAgentId?.get(payload.agent.id);
|
|
641
|
+
if (typeof snapshotUpdatedAt === "number") {
|
|
642
|
+
const updateUpdatedAt = Date.parse(payload.agent.updatedAt);
|
|
643
|
+
if (!Number.isNaN(updateUpdatedAt) && updateUpdatedAt <= snapshotUpdatedAt) {
|
|
644
|
+
continue;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
this.emit({
|
|
649
|
+
type: "agent_update",
|
|
650
|
+
payload,
|
|
651
|
+
});
|
|
591
652
|
}
|
|
592
|
-
return Object.entries(filter.labels).every(([key, value]) => agent.labels[key] === value);
|
|
593
653
|
}
|
|
594
654
|
buildFallbackProjectCheckout(cwd) {
|
|
595
655
|
return {
|
|
@@ -645,45 +705,29 @@ export class Session {
|
|
|
645
705
|
return;
|
|
646
706
|
}
|
|
647
707
|
const payload = await this.buildAgentPayload(agent);
|
|
648
|
-
const
|
|
708
|
+
const project = await this.buildProjectPlacement(payload.cwd);
|
|
709
|
+
const matches = this.matchesAgentFilter({
|
|
710
|
+
agent: payload,
|
|
711
|
+
project,
|
|
712
|
+
filter: subscription.filter,
|
|
713
|
+
});
|
|
649
714
|
if (matches) {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
715
|
+
this.bufferOrEmitAgentUpdate(subscription, {
|
|
716
|
+
kind: "upsert",
|
|
717
|
+
agent: payload,
|
|
718
|
+
project,
|
|
654
719
|
});
|
|
655
720
|
return;
|
|
656
721
|
}
|
|
657
|
-
this.
|
|
658
|
-
|
|
659
|
-
|
|
722
|
+
this.bufferOrEmitAgentUpdate(subscription, {
|
|
723
|
+
kind: "remove",
|
|
724
|
+
agentId: payload.id,
|
|
660
725
|
});
|
|
661
726
|
}
|
|
662
727
|
catch (error) {
|
|
663
728
|
this.sessionLogger.error({ err: error }, "Failed to emit agent update");
|
|
664
729
|
}
|
|
665
730
|
}
|
|
666
|
-
async emitCurrentAgentUpdatesForSubscription() {
|
|
667
|
-
const subscription = this.agentUpdatesSubscription;
|
|
668
|
-
if (!subscription) {
|
|
669
|
-
return;
|
|
670
|
-
}
|
|
671
|
-
try {
|
|
672
|
-
const agents = await this.listAgentPayloads({
|
|
673
|
-
labels: subscription.filter?.labels,
|
|
674
|
-
});
|
|
675
|
-
for (const agent of agents) {
|
|
676
|
-
const project = await this.buildProjectPlacement(agent.cwd);
|
|
677
|
-
this.emit({
|
|
678
|
-
type: "agent_update",
|
|
679
|
-
payload: { kind: "upsert", agent, project },
|
|
680
|
-
});
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
catch (error) {
|
|
684
|
-
this.sessionLogger.error({ err: error }, "Failed to emit current agent updates for subscription bootstrap");
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
731
|
/**
|
|
688
732
|
* Main entry point for processing session messages
|
|
689
733
|
*/
|
|
@@ -705,18 +749,6 @@ export class Session {
|
|
|
705
749
|
case "fetch_agent_request":
|
|
706
750
|
await this.handleFetchAgent(msg.agentId, msg.requestId);
|
|
707
751
|
break;
|
|
708
|
-
case "subscribe_agent_updates":
|
|
709
|
-
this.agentUpdatesSubscription = {
|
|
710
|
-
subscriptionId: msg.subscriptionId,
|
|
711
|
-
filter: msg.filter,
|
|
712
|
-
};
|
|
713
|
-
await this.emitCurrentAgentUpdatesForSubscription();
|
|
714
|
-
break;
|
|
715
|
-
case "unsubscribe_agent_updates":
|
|
716
|
-
if (this.agentUpdatesSubscription?.subscriptionId === msg.subscriptionId) {
|
|
717
|
-
this.agentUpdatesSubscription = null;
|
|
718
|
-
}
|
|
719
|
-
break;
|
|
720
752
|
case "delete_agent_request":
|
|
721
753
|
await this.handleDeleteAgentRequest(msg.agentId, msg.requestId);
|
|
722
754
|
break;
|
|
@@ -1058,9 +1090,9 @@ export class Session {
|
|
|
1058
1090
|
},
|
|
1059
1091
|
});
|
|
1060
1092
|
if (this.agentUpdatesSubscription) {
|
|
1061
|
-
this.
|
|
1062
|
-
|
|
1063
|
-
|
|
1093
|
+
this.bufferOrEmitAgentUpdate(this.agentUpdatesSubscription, {
|
|
1094
|
+
kind: "remove",
|
|
1095
|
+
agentId,
|
|
1064
1096
|
});
|
|
1065
1097
|
}
|
|
1066
1098
|
}
|
|
@@ -3798,20 +3830,9 @@ export class Session {
|
|
|
3798
3830
|
async listFetchAgentsEntries(request) {
|
|
3799
3831
|
const filter = request.filter;
|
|
3800
3832
|
const sort = this.normalizeFetchAgentsSort(request.sort);
|
|
3801
|
-
const
|
|
3802
|
-
let agents = await this.listAgentPayloads({
|
|
3833
|
+
const agents = await this.listAgentPayloads({
|
|
3803
3834
|
labels: filter?.labels,
|
|
3804
3835
|
});
|
|
3805
|
-
if (!includeArchived) {
|
|
3806
|
-
agents = agents.filter((agent) => !agent.archivedAt);
|
|
3807
|
-
}
|
|
3808
|
-
if (filter?.statuses && filter.statuses.length > 0) {
|
|
3809
|
-
const statuses = new Set(filter.statuses);
|
|
3810
|
-
agents = agents.filter((agent) => statuses.has(agent.status));
|
|
3811
|
-
}
|
|
3812
|
-
if (typeof filter?.requiresAttention === "boolean") {
|
|
3813
|
-
agents = agents.filter((agent) => (agent.requiresAttention ?? false) === filter.requiresAttention);
|
|
3814
|
-
}
|
|
3815
3836
|
const placementByCwd = new Map();
|
|
3816
3837
|
const getPlacement = (cwd) => {
|
|
3817
3838
|
const existing = placementByCwd.get(cwd);
|
|
@@ -3826,10 +3847,11 @@ export class Session {
|
|
|
3826
3847
|
agent,
|
|
3827
3848
|
project: await getPlacement(agent.cwd),
|
|
3828
3849
|
})));
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3850
|
+
entries = entries.filter((entry) => this.matchesAgentFilter({
|
|
3851
|
+
agent: entry.agent,
|
|
3852
|
+
project: entry.project,
|
|
3853
|
+
filter,
|
|
3854
|
+
}));
|
|
3833
3855
|
entries.sort((left, right) => this.compareFetchAgentsEntries(left, right, sort));
|
|
3834
3856
|
const cursorToken = request.page?.cursor;
|
|
3835
3857
|
if (cursorToken) {
|
|
@@ -3852,17 +3874,47 @@ export class Session {
|
|
|
3852
3874
|
};
|
|
3853
3875
|
}
|
|
3854
3876
|
async handleFetchAgents(request) {
|
|
3877
|
+
const requestedSubscriptionId = request.subscribe?.subscriptionId?.trim();
|
|
3878
|
+
const subscriptionId = request.subscribe
|
|
3879
|
+
? requestedSubscriptionId && requestedSubscriptionId.length > 0
|
|
3880
|
+
? requestedSubscriptionId
|
|
3881
|
+
: uuidv4()
|
|
3882
|
+
: null;
|
|
3855
3883
|
try {
|
|
3884
|
+
if (subscriptionId) {
|
|
3885
|
+
this.agentUpdatesSubscription = {
|
|
3886
|
+
subscriptionId,
|
|
3887
|
+
filter: request.filter,
|
|
3888
|
+
isBootstrapping: true,
|
|
3889
|
+
pendingUpdatesByAgentId: new Map(),
|
|
3890
|
+
};
|
|
3891
|
+
}
|
|
3856
3892
|
const payload = await this.listFetchAgentsEntries(request);
|
|
3893
|
+
const snapshotUpdatedAtByAgentId = new Map();
|
|
3894
|
+
for (const entry of payload.entries) {
|
|
3895
|
+
const parsedUpdatedAt = Date.parse(entry.agent.updatedAt);
|
|
3896
|
+
if (!Number.isNaN(parsedUpdatedAt)) {
|
|
3897
|
+
snapshotUpdatedAtByAgentId.set(entry.agent.id, parsedUpdatedAt);
|
|
3898
|
+
}
|
|
3899
|
+
}
|
|
3857
3900
|
this.emit({
|
|
3858
3901
|
type: "fetch_agents_response",
|
|
3859
3902
|
payload: {
|
|
3860
3903
|
requestId: request.requestId,
|
|
3904
|
+
...(subscriptionId ? { subscriptionId } : {}),
|
|
3861
3905
|
...payload,
|
|
3862
3906
|
},
|
|
3863
3907
|
});
|
|
3908
|
+
if (subscriptionId &&
|
|
3909
|
+
this.agentUpdatesSubscription?.subscriptionId === subscriptionId) {
|
|
3910
|
+
this.flushBootstrappedAgentUpdates({ snapshotUpdatedAtByAgentId });
|
|
3911
|
+
}
|
|
3864
3912
|
}
|
|
3865
3913
|
catch (error) {
|
|
3914
|
+
if (subscriptionId &&
|
|
3915
|
+
this.agentUpdatesSubscription?.subscriptionId === subscriptionId) {
|
|
3916
|
+
this.agentUpdatesSubscription = null;
|
|
3917
|
+
}
|
|
3866
3918
|
const code = error instanceof SessionRequestError ? error.code : "fetch_agents_failed";
|
|
3867
3919
|
const message = error instanceof Error ? error.message : "Failed to fetch agents";
|
|
3868
3920
|
this.sessionLogger.error({ err: error }, "Failed to handle fetch_agents_request");
|