@songsid/agend 2.1.6-beta.3 → 2.1.6-beta.4
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/agent-endpoint.d.ts +18 -0
- package/dist/agent-endpoint.js +53 -2
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/channel/mcp-server.js +9 -12
- package/dist/channel/mcp-server.js.map +1 -1
- package/dist/channel/mcp-tools.d.ts +6 -2
- package/dist/channel/mcp-tools.js +6 -36
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/config-validator.js +7 -2
- package/dist/config-validator.js.map +1 -1
- package/dist/daemon.js +12 -4
- package/dist/daemon.js.map +1 -1
- package/dist/event-log.d.ts +9 -0
- package/dist/event-log.js +21 -0
- package/dist/event-log.js.map +1 -1
- package/dist/fleet-manager.d.ts +41 -0
- package/dist/fleet-manager.js +150 -18
- package/dist/fleet-manager.js.map +1 -1
- package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +11 -1
- package/dist/tool-permissions-notice.d.ts +38 -0
- package/dist/tool-permissions-notice.js +92 -0
- package/dist/tool-permissions-notice.js.map +1 -0
- package/dist/tool-permissions.d.ts +93 -0
- package/dist/tool-permissions.js +216 -0
- package/dist/tool-permissions.js.map +1 -0
- package/package.json +1 -1
package/dist/event-log.d.ts
CHANGED
|
@@ -27,6 +27,15 @@ export declare class EventLog {
|
|
|
27
27
|
insert(instance: string, type: string, payload?: Record<string, unknown>): void;
|
|
28
28
|
query(opts?: QueryOpts): EventRow[];
|
|
29
29
|
logActivity(event: string, sender: string, summary: string, receiver?: string, detail?: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* Which tools each instance has called lately, from the activity log.
|
|
32
|
+
*
|
|
33
|
+
* `summary` is written as `tool(argument)`, so the name is everything up to
|
|
34
|
+
* the first bracket. Only the outbound path writes these rows — the agent
|
|
35
|
+
* endpoint and the typed IPC handlers do not — so this is a floor on what an
|
|
36
|
+
* instance has used, never a complete account of it.
|
|
37
|
+
*/
|
|
38
|
+
toolUseByInstance(sinceIso: string): Map<string, Map<string, number>>;
|
|
30
39
|
listActivity(opts?: {
|
|
31
40
|
since?: string;
|
|
32
41
|
limit?: number;
|
package/dist/event-log.js
CHANGED
|
@@ -93,6 +93,27 @@ export class EventLog {
|
|
|
93
93
|
logActivity(event, sender, summary, receiver, detail) {
|
|
94
94
|
this.db.prepare("INSERT INTO activity (event, sender, receiver, summary, detail) VALUES (?, ?, ?, ?, ?)").run(event, sender, receiver ?? null, summary, detail ?? null);
|
|
95
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Which tools each instance has called lately, from the activity log.
|
|
98
|
+
*
|
|
99
|
+
* `summary` is written as `tool(argument)`, so the name is everything up to
|
|
100
|
+
* the first bracket. Only the outbound path writes these rows — the agent
|
|
101
|
+
* endpoint and the typed IPC handlers do not — so this is a floor on what an
|
|
102
|
+
* instance has used, never a complete account of it.
|
|
103
|
+
*/
|
|
104
|
+
toolUseByInstance(sinceIso) {
|
|
105
|
+
const rows = this.db.prepare("SELECT sender, summary FROM activity WHERE event = 'tool_call' AND timestamp >= ?").all(sinceIso);
|
|
106
|
+
const out = new Map();
|
|
107
|
+
for (const row of rows) {
|
|
108
|
+
const tool = /^([a-z_]+)/.exec(row.summary ?? "")?.[1];
|
|
109
|
+
if (!tool || !row.sender)
|
|
110
|
+
continue;
|
|
111
|
+
const tools = out.get(row.sender) ?? new Map();
|
|
112
|
+
tools.set(tool, (tools.get(tool) ?? 0) + 1);
|
|
113
|
+
out.set(row.sender, tools);
|
|
114
|
+
}
|
|
115
|
+
return out;
|
|
116
|
+
}
|
|
96
117
|
listActivity(opts) {
|
|
97
118
|
let sql = "SELECT * FROM activity";
|
|
98
119
|
const params = [];
|
package/dist/event-log.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-log.js","sourceRoot":"","sources":["../src/event-log.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"event-log.js","sourceRoot":"","sources":["../src/event-log.ts"],"names":[],"mappings":"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"}
|
package/dist/fleet-manager.d.ts
CHANGED
|
@@ -763,6 +763,29 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
|
|
|
763
763
|
private rateLimitWarnedAt;
|
|
764
764
|
private warnIfRateLimited;
|
|
765
765
|
/** Handle outbound tool calls from a daemon instance */
|
|
766
|
+
/**
|
|
767
|
+
* Would this instance be allowed to use this tool?
|
|
768
|
+
*
|
|
769
|
+
* Stage 1 asks and records; nothing is refused yet. The recording is not only
|
|
770
|
+
* an observation window: `logActivity("tool_call")` sits on the outbound path
|
|
771
|
+
* only, so today the fleet has no idea what the agent endpoint or the typed
|
|
772
|
+
* IPC handlers are being asked to do — the one face with no authorization is
|
|
773
|
+
* also the one face with no telemetry.
|
|
774
|
+
*
|
|
775
|
+
* The profile comes from the instance the socket belongs to. Deliberately not
|
|
776
|
+
* `senderSessionName`, which arrives inside the message: a caller that fills
|
|
777
|
+
* in its own identity has not been identified.
|
|
778
|
+
*/
|
|
779
|
+
/**
|
|
780
|
+
* Say once, at startup, what the new default means for this fleet.
|
|
781
|
+
*
|
|
782
|
+
* Nothing is rewritten: an explicit `tool_set: full` is a choice somebody
|
|
783
|
+
* made, and marking an instance as a coordinator is a judgement about how
|
|
784
|
+
* their fleet is organised. Both stay theirs — this only makes sure they are
|
|
785
|
+
* not discovered by an agent failing at three in the morning.
|
|
786
|
+
*/
|
|
787
|
+
private announceToolPermissionsChange;
|
|
788
|
+
private checkToolPermission;
|
|
766
789
|
private handleOutboundFromInstance;
|
|
767
790
|
/** Side effects of a routed reply: cancel-button lifecycle, logs, SSE, chat log. */
|
|
768
791
|
private afterReplyRouted;
|
|
@@ -798,6 +821,24 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
|
|
|
798
821
|
private scheduleSourceAdapter;
|
|
799
822
|
private notifySourceTopic;
|
|
800
823
|
private notifyScheduleFailure;
|
|
824
|
+
/**
|
|
825
|
+
* The typed IPC messages, all through one door.
|
|
826
|
+
*
|
|
827
|
+
* They used to be five sibling branches on the dispatch, which is why the
|
|
828
|
+
* permission question had five places to be forgotten. Routing them together
|
|
829
|
+
* means the check above happens once and cannot be skipped by adding a
|
|
830
|
+
* sixth — a new type has to appear in `IPC_TYPE_TOOLS` to be dispatched at
|
|
831
|
+
* all.
|
|
832
|
+
*/
|
|
833
|
+
/**
|
|
834
|
+
* Answer a refused typed message the way its handler would have.
|
|
835
|
+
*
|
|
836
|
+
* These are request/response over IPC: dropping the message silently leaves
|
|
837
|
+
* the caller waiting for a reply that never comes, and a hung agent is a
|
|
838
|
+
* worse failure than a refused one.
|
|
839
|
+
*/
|
|
840
|
+
private refuseTypedIpc;
|
|
841
|
+
private dispatchTypedIpc;
|
|
801
842
|
private handleScheduleCrud;
|
|
802
843
|
private handleDecisionCrud;
|
|
803
844
|
/** Resolve display name for an instance, fallback to instance name. */
|
package/dist/fleet-manager.js
CHANGED
|
@@ -61,7 +61,9 @@ import { clearPausedMarker } from "./pause-marker.js";
|
|
|
61
61
|
import { isFleetStartCommandLine, readProcessCommandLine, releaseProcessFleetLock } from "./fleet-lock.js";
|
|
62
62
|
import { isSetupComplete, markSetupComplete } from "./setup-marker.js";
|
|
63
63
|
import { manualCleanupMessage, reapStaleTunnel } from "./tunnel/lease.js";
|
|
64
|
+
import { buildToolPermissionsNotice } from "./tool-permissions-notice.js";
|
|
64
65
|
import { GENERAL_PAUSE_ERROR, isGeneralInstance } from "./general-instance.js";
|
|
66
|
+
import { mayUseTool, resolveToolSet, toolForIpcType, toolRefusedMessage, } from "./tool-permissions.js";
|
|
65
67
|
import { decideWebGate, loadOrCreateWebToken, readWebToken } from "./web-auth.js";
|
|
66
68
|
import { fleetLevelDifferences, fleetLevelSignature } from "./fleet-level-config.js";
|
|
67
69
|
import { checkSelfRestartAllowance, recordSelfRestartAttempt } from "./self-restart-limit.js";
|
|
@@ -615,6 +617,7 @@ export class FleetManager {
|
|
|
615
617
|
// watching, and the fleet starting is the moment there is finally a process
|
|
616
618
|
// around to notice. Never throws: a lease that cannot be resolved blocks
|
|
617
619
|
// the next tunnel and says so, it does not block the fleet.
|
|
620
|
+
this.announceToolPermissionsChange();
|
|
618
621
|
void reapStaleTunnel(this.dataDir)
|
|
619
622
|
.then(outcome => {
|
|
620
623
|
if (outcome.kind === "manual")
|
|
@@ -3934,22 +3937,15 @@ export class FleetManager {
|
|
|
3934
3937
|
}
|
|
3935
3938
|
await this.handleOutboundFromInstance(name, msg);
|
|
3936
3939
|
}
|
|
3937
|
-
else if (msg.type
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
this.handleTaskCrud(name, msg);
|
|
3947
|
-
}
|
|
3948
|
-
else if (msg.type === "fleet_set_display_name") {
|
|
3949
|
-
this.handleSetDisplayName(name, msg);
|
|
3950
|
-
}
|
|
3951
|
-
else if (msg.type === "fleet_set_description") {
|
|
3952
|
-
this.handleSetDescription(name, msg);
|
|
3940
|
+
else if (toolForIpcType(msg.type) !== null) {
|
|
3941
|
+
// Sink 2 of 3. Each of these types IS a tool and reaches its own
|
|
3942
|
+
// handler without passing through the outbound path — which is how
|
|
3943
|
+
// `update_decision`, a coordinator-only tool, kept a way through.
|
|
3944
|
+
const typed = this.checkToolPermission("ipc-typed", name, toolForIpcType(msg.type));
|
|
3945
|
+
if (typed.allowed)
|
|
3946
|
+
this.dispatchTypedIpc(name, msg);
|
|
3947
|
+
else
|
|
3948
|
+
this.refuseTypedIpc(name, msg, typed.message);
|
|
3953
3949
|
}
|
|
3954
3950
|
else if (msg.type === "instance_process_state") {
|
|
3955
3951
|
this.cacheInstanceProcessStatus(name, msg.status);
|
|
@@ -4891,6 +4887,55 @@ export class FleetManager {
|
|
|
4891
4887
|
}
|
|
4892
4888
|
}
|
|
4893
4889
|
/** Handle outbound tool calls from a daemon instance */
|
|
4890
|
+
/**
|
|
4891
|
+
* Would this instance be allowed to use this tool?
|
|
4892
|
+
*
|
|
4893
|
+
* Stage 1 asks and records; nothing is refused yet. The recording is not only
|
|
4894
|
+
* an observation window: `logActivity("tool_call")` sits on the outbound path
|
|
4895
|
+
* only, so today the fleet has no idea what the agent endpoint or the typed
|
|
4896
|
+
* IPC handlers are being asked to do — the one face with no authorization is
|
|
4897
|
+
* also the one face with no telemetry.
|
|
4898
|
+
*
|
|
4899
|
+
* The profile comes from the instance the socket belongs to. Deliberately not
|
|
4900
|
+
* `senderSessionName`, which arrives inside the message: a caller that fills
|
|
4901
|
+
* in its own identity has not been identified.
|
|
4902
|
+
*/
|
|
4903
|
+
/**
|
|
4904
|
+
* Say once, at startup, what the new default means for this fleet.
|
|
4905
|
+
*
|
|
4906
|
+
* Nothing is rewritten: an explicit `tool_set: full` is a choice somebody
|
|
4907
|
+
* made, and marking an instance as a coordinator is a judgement about how
|
|
4908
|
+
* their fleet is organised. Both stay theirs — this only makes sure they are
|
|
4909
|
+
* not discovered by an agent failing at three in the morning.
|
|
4910
|
+
*/
|
|
4911
|
+
announceToolPermissionsChange() {
|
|
4912
|
+
try {
|
|
4913
|
+
const thirtyDaysAgo = new Date(Date.now() - 30 * 864e5).toISOString().slice(0, 19).replace("T", " ");
|
|
4914
|
+
const recent = [...(this.eventLog?.toolUseByInstance(thirtyDaysAgo) ?? new Map())]
|
|
4915
|
+
.map(([instance, tools]) => ({ instance, tools }));
|
|
4916
|
+
const notice = buildToolPermissionsNotice({
|
|
4917
|
+
defaultsToolSet: this.fleetConfig?.defaults?.tool_set,
|
|
4918
|
+
instances: (this.fleetConfig?.instances ?? {}),
|
|
4919
|
+
recent,
|
|
4920
|
+
});
|
|
4921
|
+
if (notice)
|
|
4922
|
+
this.logger.warn({ notice }, notice);
|
|
4923
|
+
}
|
|
4924
|
+
catch (err) {
|
|
4925
|
+
// Advice is not worth failing a startup over.
|
|
4926
|
+
this.logger.debug({ err }, "tool-permissions: could not build the migration notice");
|
|
4927
|
+
}
|
|
4928
|
+
}
|
|
4929
|
+
checkToolPermission(sink, instanceName, tool) {
|
|
4930
|
+
const profile = resolveToolSet(this.fleetConfig?.instances[instanceName], instanceName);
|
|
4931
|
+
const allowed = mayUseTool(profile, tool);
|
|
4932
|
+
if (!allowed) {
|
|
4933
|
+
this.logger.warn({ sink, instance: instanceName, profile, tool, enforced: true }, "tool-permissions: refused");
|
|
4934
|
+
return { allowed: false, message: toolRefusedMessage(profile, tool) };
|
|
4935
|
+
}
|
|
4936
|
+
this.logger.debug({ sink, instance: instanceName, profile, tool, enforced: true }, "tool-permissions: allowed");
|
|
4937
|
+
return { allowed: true, message: "" };
|
|
4938
|
+
}
|
|
4894
4939
|
async handleOutboundFromInstance(instanceName, msg) {
|
|
4895
4940
|
this.touchActivity(instanceName);
|
|
4896
4941
|
this.setTopicIcon(instanceName, "green");
|
|
@@ -4912,6 +4957,19 @@ export class FleetManager {
|
|
|
4912
4957
|
this.logger.warn({ instanceName, tool, requestId, fleetRequestId, error }, "Fleet outbound result could not be returned — instance IPC is disconnected");
|
|
4913
4958
|
}
|
|
4914
4959
|
};
|
|
4960
|
+
// Sink 1 of 3, and the first thing decided. Every MCP call and every direct
|
|
4961
|
+
// write to channel.sock lands here, whether or not mcp-server was ever
|
|
4962
|
+
// involved — which is why this is the boundary and the tool list the model
|
|
4963
|
+
// was shown is not.
|
|
4964
|
+
//
|
|
4965
|
+
// Above the adapter check on purpose: "retry shortly" is the wrong answer
|
|
4966
|
+
// to a call that will never be allowed, and an agent that believes it is a
|
|
4967
|
+
// timing problem will keep trying.
|
|
4968
|
+
const permitted = this.checkToolPermission("ipc-outbound", instanceName, tool);
|
|
4969
|
+
if (!permitted.allowed) {
|
|
4970
|
+
respond(null, permitted.message);
|
|
4971
|
+
return;
|
|
4972
|
+
}
|
|
4915
4973
|
if (this.worlds.size === 0) {
|
|
4916
4974
|
respond(null, "Channel adapters are not ready — retry shortly");
|
|
4917
4975
|
return;
|
|
@@ -5200,6 +5258,58 @@ export class FleetManager {
|
|
|
5200
5258
|
threadId: schedule.reply_thread_id ?? undefined,
|
|
5201
5259
|
}).catch((err) => this.logger.error({ err }, "Failed to send schedule failure notification"));
|
|
5202
5260
|
}
|
|
5261
|
+
/**
|
|
5262
|
+
* The typed IPC messages, all through one door.
|
|
5263
|
+
*
|
|
5264
|
+
* They used to be five sibling branches on the dispatch, which is why the
|
|
5265
|
+
* permission question had five places to be forgotten. Routing them together
|
|
5266
|
+
* means the check above happens once and cannot be skipped by adding a
|
|
5267
|
+
* sixth — a new type has to appear in `IPC_TYPE_TOOLS` to be dispatched at
|
|
5268
|
+
* all.
|
|
5269
|
+
*/
|
|
5270
|
+
/**
|
|
5271
|
+
* Answer a refused typed message the way its handler would have.
|
|
5272
|
+
*
|
|
5273
|
+
* These are request/response over IPC: dropping the message silently leaves
|
|
5274
|
+
* the caller waiting for a reply that never comes, and a hung agent is a
|
|
5275
|
+
* worse failure than a refused one.
|
|
5276
|
+
*/
|
|
5277
|
+
refuseTypedIpc(name, msg, message) {
|
|
5278
|
+
const ipc = this.instanceIpcClients.get(name);
|
|
5279
|
+
const fleetRequestId = msg.fleetRequestId;
|
|
5280
|
+
if (!ipc || !fleetRequestId)
|
|
5281
|
+
return;
|
|
5282
|
+
const type = String(msg.type);
|
|
5283
|
+
const responseType = type.startsWith("fleet_schedule_") ? "fleet_schedule_response"
|
|
5284
|
+
: type.startsWith("fleet_decision_") ? "fleet_decision_response"
|
|
5285
|
+
: type === "fleet_task" ? "fleet_task_response"
|
|
5286
|
+
: type === "fleet_set_display_name" ? "fleet_display_name_response"
|
|
5287
|
+
: "fleet_description_response";
|
|
5288
|
+
ipc.send({ type: responseType, fleetRequestId, error: message });
|
|
5289
|
+
}
|
|
5290
|
+
dispatchTypedIpc(name, msg) {
|
|
5291
|
+
const type = String(msg.type);
|
|
5292
|
+
if (type.startsWith("fleet_schedule_")) {
|
|
5293
|
+
this.handleScheduleCrud(name, msg);
|
|
5294
|
+
return;
|
|
5295
|
+
}
|
|
5296
|
+
if (type.startsWith("fleet_decision_")) {
|
|
5297
|
+
this.handleDecisionCrud(name, msg);
|
|
5298
|
+
return;
|
|
5299
|
+
}
|
|
5300
|
+
if (type === "fleet_task") {
|
|
5301
|
+
this.handleTaskCrud(name, msg);
|
|
5302
|
+
return;
|
|
5303
|
+
}
|
|
5304
|
+
if (type === "fleet_set_display_name") {
|
|
5305
|
+
this.handleSetDisplayName(name, msg);
|
|
5306
|
+
return;
|
|
5307
|
+
}
|
|
5308
|
+
if (type === "fleet_set_description") {
|
|
5309
|
+
this.handleSetDescription(name, msg);
|
|
5310
|
+
return;
|
|
5311
|
+
}
|
|
5312
|
+
}
|
|
5203
5313
|
handleScheduleCrud(instanceName, msg) {
|
|
5204
5314
|
const fleetRequestId = msg.fleetRequestId;
|
|
5205
5315
|
const payload = (msg.payload ?? {});
|
|
@@ -5207,6 +5317,14 @@ export class FleetManager {
|
|
|
5207
5317
|
const ipc = this.instanceIpcClients.get(instanceName);
|
|
5208
5318
|
if (!ipc)
|
|
5209
5319
|
return;
|
|
5320
|
+
if (!this.scheduler) {
|
|
5321
|
+
// It did answer before, with whatever TypeError fell out of the try
|
|
5322
|
+
// block — "Cannot read properties of null (reading 'list')" is a stack
|
|
5323
|
+
// trace wearing an error message, and the agent reading it cannot tell
|
|
5324
|
+
// that the fleet simply has no scheduler.
|
|
5325
|
+
ipc.send({ type: "fleet_schedule_response", fleetRequestId, error: "Schedules are unavailable — the fleet scheduler is not running" });
|
|
5326
|
+
return;
|
|
5327
|
+
}
|
|
5210
5328
|
try {
|
|
5211
5329
|
let result;
|
|
5212
5330
|
switch (msg.type) {
|
|
@@ -5248,8 +5366,15 @@ export class FleetManager {
|
|
|
5248
5366
|
const payload = (msg.payload ?? {});
|
|
5249
5367
|
const meta = (msg.meta ?? {});
|
|
5250
5368
|
const ipc = this.instanceIpcClients.get(instanceName);
|
|
5251
|
-
if (!ipc
|
|
5369
|
+
if (!ipc)
|
|
5370
|
+
return;
|
|
5371
|
+
if (!this.scheduler) {
|
|
5372
|
+
// Returning silently left the caller waiting for a response that was
|
|
5373
|
+
// never coming. Over IPC that is a hang, and a hang is a worse answer
|
|
5374
|
+
// than an error.
|
|
5375
|
+
ipc.send({ type: "fleet_decision_response", fleetRequestId, error: "Decisions are unavailable — the fleet scheduler is not running" });
|
|
5252
5376
|
return;
|
|
5377
|
+
}
|
|
5253
5378
|
const db = this.scheduler.db;
|
|
5254
5379
|
const projectRoot = meta.working_directory || this.fleetConfig?.instances[instanceName]?.working_directory || "";
|
|
5255
5380
|
try {
|
|
@@ -5523,8 +5648,15 @@ export class FleetManager {
|
|
|
5523
5648
|
const payload = (msg.payload ?? {});
|
|
5524
5649
|
const meta = (msg.meta ?? {});
|
|
5525
5650
|
const ipc = this.instanceIpcClients.get(instanceName);
|
|
5526
|
-
if (!ipc
|
|
5651
|
+
if (!ipc)
|
|
5652
|
+
return;
|
|
5653
|
+
if (!this.scheduler) {
|
|
5654
|
+
// Returning silently left the caller waiting for a response that was
|
|
5655
|
+
// never coming. Over IPC that is a hang, and a hang is a worse answer
|
|
5656
|
+
// than an error.
|
|
5657
|
+
ipc.send({ type: "fleet_task_response", fleetRequestId, error: "The task board is unavailable — the fleet scheduler is not running" });
|
|
5527
5658
|
return;
|
|
5659
|
+
}
|
|
5528
5660
|
const db = this.scheduler.db;
|
|
5529
5661
|
const action = payload.action;
|
|
5530
5662
|
try {
|