@ctliz/agent-intercom-codex 0.11.0-connect.2 → 0.12.0-connect.2
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/broker/spawn.ts +2 -0
- package/codex/app-server-client.ts +2 -0
- package/codex/clipboard.ts +2 -2
- package/codex/coi.ts +4 -1
- package/codex/mcp-protocol.ts +16 -1
- package/codex/runtime.ts +19 -3
- package/codex/team.ts +244 -17
- package/dist/bridge-daemon.mjs +149 -17
- package/dist/broker.mjs +1 -1
- package/dist/build-info.json +2 -2
- package/dist/codex-server.mjs +172 -19
- package/dist/coi.mjs +158 -23
- package/package.json +3 -3
package/dist/bridge-daemon.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
process.stderr.write("[agent-intercom-build] package=@ctliz/agent-intercom-codex version=0.
|
|
2
|
+
process.stderr.write("[agent-intercom-build] package=@ctliz/agent-intercom-codex version=0.12.0-connect.2 target=bridge-daemon sourceSha256=618efd98d8b0f52e066dbc535b3d8f61e7221d9f6c40cb2a3a1da690cbcae849\n");
|
|
3
3
|
|
|
4
4
|
// codex/bridge-daemon.ts
|
|
5
5
|
import { once } from "node:events";
|
|
@@ -95,7 +95,8 @@ var CodexAppServerClient = class extends EventEmitter {
|
|
|
95
95
|
const started = spawnSync(this.options.startDaemonCommand, this.options.startDaemonArgs, {
|
|
96
96
|
encoding: "utf8",
|
|
97
97
|
env: this.options.env,
|
|
98
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
98
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
99
|
+
shell: false
|
|
99
100
|
});
|
|
100
101
|
if (started.status !== 0) {
|
|
101
102
|
throw new Error(`Failed to start Codex app-server daemon: ${started.stderr || started.stdout || `exit ${started.status}`}`);
|
|
@@ -108,7 +109,8 @@ var CodexAppServerClient = class extends EventEmitter {
|
|
|
108
109
|
}
|
|
109
110
|
const proc = spawn(this.options.command, this.options.args, {
|
|
110
111
|
stdio: ["pipe", "pipe", "pipe"],
|
|
111
|
-
env: this.options.env
|
|
112
|
+
env: this.options.env,
|
|
113
|
+
shell: false
|
|
112
114
|
});
|
|
113
115
|
this.proc = proc;
|
|
114
116
|
this.rl = readline.createInterface({ input: proc.stdout, crlfDelay: Infinity });
|
|
@@ -2435,7 +2437,8 @@ function getBrokerSpawnOptions(extensionDir = EXTENSION_DIR, env = process.env)
|
|
|
2435
2437
|
stdio: "ignore",
|
|
2436
2438
|
cwd: extensionDir,
|
|
2437
2439
|
env: { ...env, PI_CODING_AGENT_DIR: getAgentDirPath(env), NODE_NO_WARNINGS: "1" },
|
|
2438
|
-
windowsHide: true
|
|
2440
|
+
windowsHide: true,
|
|
2441
|
+
shell: false
|
|
2439
2442
|
};
|
|
2440
2443
|
}
|
|
2441
2444
|
function toError2(error) {
|
|
@@ -2808,6 +2811,7 @@ import {
|
|
|
2808
2811
|
parseWorkerIdentityV2 as parseWorkerIdentityV22,
|
|
2809
2812
|
workerIdentityFromEnvironment
|
|
2810
2813
|
} from "@ctliz/agent-intercom-core/boss";
|
|
2814
|
+
import { readTeamManifestAsync, TeamManifestError } from "@ctliz/agent-intercom-core/team-manifest";
|
|
2811
2815
|
var LEGACY_LIVE_STATES = /* @__PURE__ */ new Set(["provisioning", "running", "idle", "needs_attention", "stopping"]);
|
|
2812
2816
|
var CANONICAL_LIVE_STATES = /* @__PURE__ */ new Set(["provisioning", "registering", "ready", "working", "waiting", "paused", "stalled", "blocked", "unreachable"]);
|
|
2813
2817
|
var stringValue = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
@@ -2815,12 +2819,25 @@ var connectedTo = (sessions, target) => {
|
|
|
2815
2819
|
const normalized = target.toLowerCase();
|
|
2816
2820
|
return sessions.some((session) => session.id === target || session.name?.toLowerCase() === normalized);
|
|
2817
2821
|
};
|
|
2822
|
+
function hasBossEnvironmentKeys(env) {
|
|
2823
|
+
const bossKeys = [
|
|
2824
|
+
"AGENT_INTERCOM_BOSS_RUN_ID",
|
|
2825
|
+
"AGENT_INTERCOM_PARTICIPANT_ID",
|
|
2826
|
+
"AGENT_INTERCOM_BINDING_EPOCH",
|
|
2827
|
+
"AGENT_INTERCOM_WORKER_INCARNATION_ID",
|
|
2828
|
+
"AGENT_INTERCOM_WORKER_GENERATION"
|
|
2829
|
+
];
|
|
2830
|
+
return bossKeys.some((key) => env[key] !== void 0);
|
|
2831
|
+
}
|
|
2818
2832
|
function bossIdentityFromEnvironment(env) {
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2833
|
+
if (!hasBossEnvironmentKeys(env)) return void 0;
|
|
2834
|
+
try {
|
|
2835
|
+
const identity = workerIdentityFromEnvironment(env);
|
|
2836
|
+
if (!("bossRunId" in identity)) return void 0;
|
|
2837
|
+
return identity;
|
|
2838
|
+
} catch {
|
|
2839
|
+
return void 0;
|
|
2840
|
+
}
|
|
2824
2841
|
}
|
|
2825
2842
|
function canonicalWorker(value) {
|
|
2826
2843
|
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error("worker must be an object");
|
|
@@ -2874,25 +2891,138 @@ async function readWorkers(agentDir) {
|
|
|
2874
2891
|
return { version: 1, workers: [] };
|
|
2875
2892
|
}
|
|
2876
2893
|
}
|
|
2894
|
+
async function resolveNonAuthoritativeTeam(input, env) {
|
|
2895
|
+
if (env.AGENT_INTERCOM_TEAM_MANIFEST !== void 0) {
|
|
2896
|
+
const rawPath = env.AGENT_INTERCOM_TEAM_MANIFEST.trim();
|
|
2897
|
+
if (!rawPath) {
|
|
2898
|
+
throw new TeamManifestError("ERR_TEAM_MANIFEST_INVALID");
|
|
2899
|
+
}
|
|
2900
|
+
const manifest = await readTeamManifestAsync(rawPath);
|
|
2901
|
+
if (!manifest) {
|
|
2902
|
+
throw new TeamManifestError("ERR_TEAM_MANIFEST_INVALID");
|
|
2903
|
+
}
|
|
2904
|
+
const selfMember = manifest.members.find((m) => m.sessionId === input.selfId);
|
|
2905
|
+
if (!selfMember) {
|
|
2906
|
+
throw new TeamManifestError("ERR_TEAM_MANIFEST_INVALID");
|
|
2907
|
+
}
|
|
2908
|
+
const isManager = input.selfId === manifest.leadId;
|
|
2909
|
+
const managerTarget2 = manifest.leadId;
|
|
2910
|
+
const managerConnected = connectedTo(input.sessions, managerTarget2);
|
|
2911
|
+
const coworkers = manifest.members.filter((m) => m.sessionId !== input.selfId).filter((m) => isManager || m.sessionId !== managerTarget2).map((m) => {
|
|
2912
|
+
const live = input.sessions.find((s) => s.id === m.sessionId || s.name === m.sessionId);
|
|
2913
|
+
return {
|
|
2914
|
+
id: m.sessionId,
|
|
2915
|
+
target: m.sessionId,
|
|
2916
|
+
role: m.role,
|
|
2917
|
+
connected: Boolean(live)
|
|
2918
|
+
};
|
|
2919
|
+
});
|
|
2920
|
+
return {
|
|
2921
|
+
teamId: manifest.runId,
|
|
2922
|
+
self: { id: input.selfId, isManager },
|
|
2923
|
+
manager: { target: managerTarget2, connected: managerConnected },
|
|
2924
|
+
coworkers,
|
|
2925
|
+
source: "manifest"
|
|
2926
|
+
};
|
|
2927
|
+
}
|
|
2928
|
+
if (stringValue(env.AGENT_INTERCOM_SCOPE_ID)) {
|
|
2929
|
+
const managerTarget2 = stringValue(env.AGENT_INTERCOM_MANAGER_TARGET) ?? stringValue(env.AGENT_INTERCOM_MANAGER_SESSION_ID);
|
|
2930
|
+
const role = stringValue(env.AGENT_INTERCOM_ROLE)?.toLowerCase();
|
|
2931
|
+
const isManager = role === "manager" || managerTarget2 !== void 0 && managerTarget2 === input.selfId || managerTarget2 === void 0 && role !== "worker";
|
|
2932
|
+
const effectiveManagerTarget = isManager ? input.selfId : managerTarget2;
|
|
2933
|
+
const coworkers = input.sessions.filter((session) => session.id !== input.selfId).filter((session) => session.model !== "human").filter((session) => session.id !== effectiveManagerTarget).map((session) => ({
|
|
2934
|
+
id: session.id,
|
|
2935
|
+
target: session.id,
|
|
2936
|
+
...session.model ? { harness: session.model } : {},
|
|
2937
|
+
connected: true
|
|
2938
|
+
}));
|
|
2939
|
+
const manager = effectiveManagerTarget ? {
|
|
2940
|
+
target: effectiveManagerTarget,
|
|
2941
|
+
connected: isManager ? true : connectedTo(input.sessions, effectiveManagerTarget)
|
|
2942
|
+
} : void 0;
|
|
2943
|
+
return {
|
|
2944
|
+
teamId: effectiveManagerTarget ?? input.selfId,
|
|
2945
|
+
self: { id: input.selfId, isManager },
|
|
2946
|
+
...manager ? { manager } : {},
|
|
2947
|
+
coworkers,
|
|
2948
|
+
source: "live"
|
|
2949
|
+
};
|
|
2950
|
+
}
|
|
2951
|
+
const managerTarget = stringValue(env.AGENT_INTERCOM_MANAGER_TARGET) ?? stringValue(env.AGENT_INTERCOM_MANAGER_SESSION_ID);
|
|
2952
|
+
return {
|
|
2953
|
+
teamId: managerTarget ?? input.selfId,
|
|
2954
|
+
self: { id: input.selfId, isManager: !managerTarget },
|
|
2955
|
+
manager: managerTarget ? { target: managerTarget, connected: connectedTo(input.sessions, managerTarget) } : { target: input.selfId, connected: true },
|
|
2956
|
+
coworkers: [],
|
|
2957
|
+
source: "standalone"
|
|
2958
|
+
};
|
|
2959
|
+
}
|
|
2877
2960
|
async function resolveIntercomTeam(input) {
|
|
2878
2961
|
const env = input.env ?? process.env;
|
|
2879
2962
|
const snapshot = await readWorkers(input.agentDir ?? getAgentDirPath());
|
|
2880
2963
|
const workers = snapshot.workers;
|
|
2881
2964
|
const workerId = stringValue(env.AGENT_INTERCOM_WORKER_ID);
|
|
2965
|
+
const selfSession = input.sessions.find((session) => session.id === input.selfId);
|
|
2966
|
+
const isBossContext = selfSession?.boss !== void 0 || hasBossEnvironmentKeys(env);
|
|
2882
2967
|
const bossIdentity = bossIdentityFromEnvironment(env);
|
|
2883
2968
|
const runId = stringValue(env.AGENT_INTERCOM_RUN_ID);
|
|
2884
|
-
|
|
2969
|
+
if (isBossContext && bossIdentity === void 0) {
|
|
2970
|
+
return {
|
|
2971
|
+
self: { id: input.selfId, ...workerId ? { workerId } : {}, isManager: false },
|
|
2972
|
+
coworkers: [],
|
|
2973
|
+
source: "boss"
|
|
2974
|
+
};
|
|
2975
|
+
}
|
|
2976
|
+
const currentMatches = workerId ? workers.filter((worker) => stringValue(worker.id) === workerId && (bossIdentity === void 0 ? snapshot.version === 1 && (!runId || stringValue(worker.runId) === runId) : snapshot.version === 2 && worker.canonicalIdentity?.workerId === bossIdentity.workerId && worker.canonicalIdentity.workerIncarnationId === bossIdentity.workerIncarnationId && worker.canonicalIdentity.workerGeneration === bossIdentity.workerGeneration && "bossRunId" in worker.canonicalIdentity && "bossRunId" in bossIdentity && worker.canonicalIdentity.bossRunId === bossIdentity.bossRunId && worker.canonicalIdentity.participantId === bossIdentity.participantId && worker.canonicalIdentity.bindingEpoch === bossIdentity.bindingEpoch)) : [];
|
|
2885
2977
|
const current = bossIdentity === void 0 ? currentMatches[0] : currentMatches.length === 1 ? currentMatches[0] : void 0;
|
|
2886
2978
|
const currentTarget = stringValue(current?.intercomTarget);
|
|
2887
2979
|
const exactCurrentProjection = current !== void 0 && currentTarget === input.selfId && workers.filter((worker) => stringValue(worker.id) === workerId).length === 1 && workers.filter((worker) => stringValue(worker.intercomTarget) === currentTarget).length === 1 && exactBossRosterSession(input.sessions, current) !== void 0;
|
|
2888
2980
|
if (bossIdentity !== void 0 && !exactCurrentProjection) {
|
|
2889
|
-
return { self: { id: input.selfId, ...workerId ? { workerId } : {}, isManager: false }, coworkers: [] };
|
|
2981
|
+
return { self: { id: input.selfId, ...workerId ? { workerId } : {}, isManager: false }, coworkers: [], source: "boss" };
|
|
2982
|
+
}
|
|
2983
|
+
if (bossIdentity === void 0 && !current) {
|
|
2984
|
+
if (workerId === void 0 && snapshot.version === 1) {
|
|
2985
|
+
const ownedCoworkers = workers.filter((worker) => worker.owned === true).filter((worker) => {
|
|
2986
|
+
const mgr = stringValue(worker.managerSessionId);
|
|
2987
|
+
return mgr !== void 0 && mgr === input.selfId;
|
|
2988
|
+
}).filter((worker) => LEGACY_LIVE_STATES.has(stringValue(worker.state) ?? "")).filter((worker) => stringValue(worker.id) !== input.selfId).map((worker) => {
|
|
2989
|
+
const id = stringValue(worker.id);
|
|
2990
|
+
if (!id) return void 0;
|
|
2991
|
+
const target = stringValue(worker.intercomTarget) ?? id;
|
|
2992
|
+
return {
|
|
2993
|
+
id,
|
|
2994
|
+
target,
|
|
2995
|
+
...stringValue(worker.harness) ? { harness: stringValue(worker.harness) } : {},
|
|
2996
|
+
...stringValue(worker.role) ? { role: stringValue(worker.role) } : {},
|
|
2997
|
+
...stringValue(worker.state) ? { state: stringValue(worker.state) } : {},
|
|
2998
|
+
connected: connectedTo(input.sessions, target)
|
|
2999
|
+
};
|
|
3000
|
+
}).filter((member) => Boolean(member));
|
|
3001
|
+
if (ownedCoworkers.length > 0) {
|
|
3002
|
+
return {
|
|
3003
|
+
teamId: input.selfId,
|
|
3004
|
+
self: { id: input.selfId, isManager: true },
|
|
3005
|
+
manager: { target: input.selfId, connected: true },
|
|
3006
|
+
coworkers: ownedCoworkers,
|
|
3007
|
+
source: "orchestrator"
|
|
3008
|
+
};
|
|
3009
|
+
}
|
|
3010
|
+
}
|
|
3011
|
+
return resolveNonAuthoritativeTeam(input, env);
|
|
2890
3012
|
}
|
|
2891
|
-
const managerTarget = stringValue(current?.managerSessionId) ?? (bossIdentity === void 0 ? stringValue(env.AGENT_INTERCOM_MANAGER_TARGET) ?? stringValue(env.AGENT_INTERCOM_MANAGER_SESSION_ID) : void 0);
|
|
2892
|
-
const teamId = managerTarget ?? input.selfId;
|
|
2893
3013
|
const currentRole = stringValue(current?.role);
|
|
3014
|
+
const selfIsManager = bossIdentity !== void 0 ? currentRole === "manager" : void 0;
|
|
3015
|
+
const managerTarget = bossIdentity !== void 0 ? selfIsManager ? input.selfId : stringValue(current?.managerSessionId) : stringValue(current?.managerSessionId) ?? stringValue(env.AGENT_INTERCOM_MANAGER_TARGET) ?? stringValue(env.AGENT_INTERCOM_MANAGER_SESSION_ID);
|
|
3016
|
+
if (bossIdentity === void 0 && !managerTarget) {
|
|
3017
|
+
return {
|
|
3018
|
+
self: { id: input.selfId, ...workerId ? { workerId } : {}, isManager: false },
|
|
3019
|
+
coworkers: [],
|
|
3020
|
+
source: "orchestrator"
|
|
3021
|
+
};
|
|
3022
|
+
}
|
|
3023
|
+
const teamId = bossIdentity !== void 0 ? "bossRunId" in bossIdentity ? bossIdentity.bossRunId : managerTarget ?? input.selfId : managerTarget ?? input.selfId;
|
|
2894
3024
|
const canDiscoverOwnedRoster = bossIdentity === void 0 || currentRole === "manager" || currentRole === "controller";
|
|
2895
|
-
const coworkers = (canDiscoverOwnedRoster ? workers : []).filter((worker) => worker.owned === true).filter((worker) => bossIdentity === void 0 || snapshot.version === 2 && worker.canonicalIdentity !== void 0 && "bossRunId" in worker.canonicalIdentity && "bossRunId" in bossIdentity && worker.canonicalIdentity.bossRunId === bossIdentity.bossRunId).filter((worker) => stringValue(worker.managerSessionId) === teamId).filter((worker) => stringValue(worker.intercomTarget) !== managerTarget).filter((worker) => (snapshot.version === 2 ? CANONICAL_LIVE_STATES : LEGACY_LIVE_STATES).has(stringValue(worker.state) ?? "")).filter((worker) => stringValue(worker.id) !== workerId).map((worker) => {
|
|
3025
|
+
const coworkers = (canDiscoverOwnedRoster ? workers : []).filter((worker) => worker.owned === true).filter((worker) => bossIdentity === void 0 || snapshot.version === 2 && worker.canonicalIdentity !== void 0 && "bossRunId" in worker.canonicalIdentity && "bossRunId" in bossIdentity && worker.canonicalIdentity.bossRunId === bossIdentity.bossRunId).filter((worker) => stringValue(worker.managerSessionId) === (bossIdentity !== void 0 ? managerTarget : teamId)).filter((worker) => stringValue(worker.intercomTarget) !== managerTarget).filter((worker) => (snapshot.version === 2 ? CANONICAL_LIVE_STATES : LEGACY_LIVE_STATES).has(stringValue(worker.state) ?? "")).filter((worker) => stringValue(worker.id) !== workerId && stringValue(worker.id) !== input.selfId).map((worker) => {
|
|
2896
3026
|
const id = stringValue(worker.id);
|
|
2897
3027
|
if (!id) return void 0;
|
|
2898
3028
|
const target = stringValue(worker.intercomTarget) ?? id;
|
|
@@ -2909,11 +3039,13 @@ async function resolveIntercomTeam(input) {
|
|
|
2909
3039
|
}).filter((member) => Boolean(member));
|
|
2910
3040
|
const managerWorker = managerTarget === void 0 ? void 0 : workers.find((worker) => stringValue(worker.intercomTarget) === managerTarget && (bossIdentity === void 0 || snapshot.version === 2 && stringValue(worker.role) === "manager" && worker.canonicalIdentity !== void 0 && "bossRunId" in worker.canonicalIdentity && "bossRunId" in bossIdentity && worker.canonicalIdentity.bossRunId === bossIdentity.bossRunId));
|
|
2911
3041
|
const managerConnected = managerTarget === void 0 ? true : bossIdentity === void 0 ? connectedTo(input.sessions, managerTarget) : managerWorker !== void 0 && exactBossRosterSession(input.sessions, managerWorker) !== void 0;
|
|
3042
|
+
const isManager = bossIdentity !== void 0 ? selfIsManager : false;
|
|
2912
3043
|
return {
|
|
2913
3044
|
teamId,
|
|
2914
|
-
self: { id: input.selfId, ...workerId ? { workerId } : {}, isManager
|
|
2915
|
-
...managerTarget ? { manager: { target: managerTarget, connected:
|
|
2916
|
-
coworkers
|
|
3045
|
+
self: { id: input.selfId, ...workerId ? { workerId } : {}, isManager },
|
|
3046
|
+
...managerTarget ? { manager: { target: managerTarget, connected: isManager ? true : managerConnected } } : {},
|
|
3047
|
+
coworkers,
|
|
3048
|
+
source: bossIdentity !== void 0 ? "boss" : "orchestrator"
|
|
2917
3049
|
};
|
|
2918
3050
|
}
|
|
2919
3051
|
function formatIntercomTeam(team) {
|
package/dist/broker.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
process.stderr.write("[agent-intercom-build] package=@ctliz/agent-intercom-codex version=0.
|
|
1
|
+
process.stderr.write("[agent-intercom-build] package=@ctliz/agent-intercom-codex version=0.12.0-connect.2 target=broker sourceSha256=618efd98d8b0f52e066dbc535b3d8f61e7221d9f6c40cb2a3a1da690cbcae849\n");
|
|
2
2
|
|
|
3
3
|
// broker/broker.ts
|
|
4
4
|
import net from "net";
|
package/dist/build-info.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"package": "@ctliz/agent-intercom-codex",
|
|
4
|
-
"version": "0.
|
|
5
|
-
"sourceSha256": "
|
|
4
|
+
"version": "0.12.0-connect.2",
|
|
5
|
+
"sourceSha256": "618efd98d8b0f52e066dbc535b3d8f61e7221d9f6c40cb2a3a1da690cbcae849",
|
|
6
6
|
"targets": [
|
|
7
7
|
"codex-server",
|
|
8
8
|
"broker",
|
package/dist/codex-server.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
process.stderr.write("[agent-intercom-build] package=@ctliz/agent-intercom-codex version=0.
|
|
2
|
+
process.stderr.write("[agent-intercom-build] package=@ctliz/agent-intercom-codex version=0.12.0-connect.2 target=codex-server sourceSha256=618efd98d8b0f52e066dbc535b3d8f61e7221d9f6c40cb2a3a1da690cbcae849\n");
|
|
3
3
|
|
|
4
4
|
// codex/server.ts
|
|
5
5
|
import readline from "node:readline";
|
|
@@ -1738,7 +1738,8 @@ function getBrokerSpawnOptions(extensionDir = EXTENSION_DIR, env = process.env)
|
|
|
1738
1738
|
stdio: "ignore",
|
|
1739
1739
|
cwd: extensionDir,
|
|
1740
1740
|
env: { ...env, PI_CODING_AGENT_DIR: getAgentDirPath(env), NODE_NO_WARNINGS: "1" },
|
|
1741
|
-
windowsHide: true
|
|
1741
|
+
windowsHide: true,
|
|
1742
|
+
shell: false
|
|
1742
1743
|
};
|
|
1743
1744
|
}
|
|
1744
1745
|
function toError2(error2) {
|
|
@@ -2089,6 +2090,7 @@ import {
|
|
|
2089
2090
|
parseWorkerIdentityV2 as parseWorkerIdentityV22,
|
|
2090
2091
|
workerIdentityFromEnvironment
|
|
2091
2092
|
} from "@ctliz/agent-intercom-core/boss";
|
|
2093
|
+
import { readTeamManifestAsync, TeamManifestError } from "@ctliz/agent-intercom-core/team-manifest";
|
|
2092
2094
|
var LEGACY_LIVE_STATES = /* @__PURE__ */ new Set(["provisioning", "running", "idle", "needs_attention", "stopping"]);
|
|
2093
2095
|
var CANONICAL_LIVE_STATES = /* @__PURE__ */ new Set(["provisioning", "registering", "ready", "working", "waiting", "paused", "stalled", "blocked", "unreachable"]);
|
|
2094
2096
|
var stringValue = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
@@ -2096,12 +2098,25 @@ var connectedTo = (sessions, target) => {
|
|
|
2096
2098
|
const normalized = target.toLowerCase();
|
|
2097
2099
|
return sessions.some((session) => session.id === target || session.name?.toLowerCase() === normalized);
|
|
2098
2100
|
};
|
|
2101
|
+
function hasBossEnvironmentKeys(env) {
|
|
2102
|
+
const bossKeys = [
|
|
2103
|
+
"AGENT_INTERCOM_BOSS_RUN_ID",
|
|
2104
|
+
"AGENT_INTERCOM_PARTICIPANT_ID",
|
|
2105
|
+
"AGENT_INTERCOM_BINDING_EPOCH",
|
|
2106
|
+
"AGENT_INTERCOM_WORKER_INCARNATION_ID",
|
|
2107
|
+
"AGENT_INTERCOM_WORKER_GENERATION"
|
|
2108
|
+
];
|
|
2109
|
+
return bossKeys.some((key) => env[key] !== void 0);
|
|
2110
|
+
}
|
|
2099
2111
|
function bossIdentityFromEnvironment(env) {
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2112
|
+
if (!hasBossEnvironmentKeys(env)) return void 0;
|
|
2113
|
+
try {
|
|
2114
|
+
const identity = workerIdentityFromEnvironment(env);
|
|
2115
|
+
if (!("bossRunId" in identity)) return void 0;
|
|
2116
|
+
return identity;
|
|
2117
|
+
} catch {
|
|
2118
|
+
return void 0;
|
|
2119
|
+
}
|
|
2105
2120
|
}
|
|
2106
2121
|
function canonicalWorker(value) {
|
|
2107
2122
|
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error("worker must be an object");
|
|
@@ -2155,25 +2170,138 @@ async function readWorkers(agentDir) {
|
|
|
2155
2170
|
return { version: 1, workers: [] };
|
|
2156
2171
|
}
|
|
2157
2172
|
}
|
|
2173
|
+
async function resolveNonAuthoritativeTeam(input, env) {
|
|
2174
|
+
if (env.AGENT_INTERCOM_TEAM_MANIFEST !== void 0) {
|
|
2175
|
+
const rawPath = env.AGENT_INTERCOM_TEAM_MANIFEST.trim();
|
|
2176
|
+
if (!rawPath) {
|
|
2177
|
+
throw new TeamManifestError("ERR_TEAM_MANIFEST_INVALID");
|
|
2178
|
+
}
|
|
2179
|
+
const manifest = await readTeamManifestAsync(rawPath);
|
|
2180
|
+
if (!manifest) {
|
|
2181
|
+
throw new TeamManifestError("ERR_TEAM_MANIFEST_INVALID");
|
|
2182
|
+
}
|
|
2183
|
+
const selfMember = manifest.members.find((m) => m.sessionId === input.selfId);
|
|
2184
|
+
if (!selfMember) {
|
|
2185
|
+
throw new TeamManifestError("ERR_TEAM_MANIFEST_INVALID");
|
|
2186
|
+
}
|
|
2187
|
+
const isManager = input.selfId === manifest.leadId;
|
|
2188
|
+
const managerTarget2 = manifest.leadId;
|
|
2189
|
+
const managerConnected = connectedTo(input.sessions, managerTarget2);
|
|
2190
|
+
const coworkers = manifest.members.filter((m) => m.sessionId !== input.selfId).filter((m) => isManager || m.sessionId !== managerTarget2).map((m) => {
|
|
2191
|
+
const live = input.sessions.find((s) => s.id === m.sessionId || s.name === m.sessionId);
|
|
2192
|
+
return {
|
|
2193
|
+
id: m.sessionId,
|
|
2194
|
+
target: m.sessionId,
|
|
2195
|
+
role: m.role,
|
|
2196
|
+
connected: Boolean(live)
|
|
2197
|
+
};
|
|
2198
|
+
});
|
|
2199
|
+
return {
|
|
2200
|
+
teamId: manifest.runId,
|
|
2201
|
+
self: { id: input.selfId, isManager },
|
|
2202
|
+
manager: { target: managerTarget2, connected: managerConnected },
|
|
2203
|
+
coworkers,
|
|
2204
|
+
source: "manifest"
|
|
2205
|
+
};
|
|
2206
|
+
}
|
|
2207
|
+
if (stringValue(env.AGENT_INTERCOM_SCOPE_ID)) {
|
|
2208
|
+
const managerTarget2 = stringValue(env.AGENT_INTERCOM_MANAGER_TARGET) ?? stringValue(env.AGENT_INTERCOM_MANAGER_SESSION_ID);
|
|
2209
|
+
const role = stringValue(env.AGENT_INTERCOM_ROLE)?.toLowerCase();
|
|
2210
|
+
const isManager = role === "manager" || managerTarget2 !== void 0 && managerTarget2 === input.selfId || managerTarget2 === void 0 && role !== "worker";
|
|
2211
|
+
const effectiveManagerTarget = isManager ? input.selfId : managerTarget2;
|
|
2212
|
+
const coworkers = input.sessions.filter((session) => session.id !== input.selfId).filter((session) => session.model !== "human").filter((session) => session.id !== effectiveManagerTarget).map((session) => ({
|
|
2213
|
+
id: session.id,
|
|
2214
|
+
target: session.id,
|
|
2215
|
+
...session.model ? { harness: session.model } : {},
|
|
2216
|
+
connected: true
|
|
2217
|
+
}));
|
|
2218
|
+
const manager = effectiveManagerTarget ? {
|
|
2219
|
+
target: effectiveManagerTarget,
|
|
2220
|
+
connected: isManager ? true : connectedTo(input.sessions, effectiveManagerTarget)
|
|
2221
|
+
} : void 0;
|
|
2222
|
+
return {
|
|
2223
|
+
teamId: effectiveManagerTarget ?? input.selfId,
|
|
2224
|
+
self: { id: input.selfId, isManager },
|
|
2225
|
+
...manager ? { manager } : {},
|
|
2226
|
+
coworkers,
|
|
2227
|
+
source: "live"
|
|
2228
|
+
};
|
|
2229
|
+
}
|
|
2230
|
+
const managerTarget = stringValue(env.AGENT_INTERCOM_MANAGER_TARGET) ?? stringValue(env.AGENT_INTERCOM_MANAGER_SESSION_ID);
|
|
2231
|
+
return {
|
|
2232
|
+
teamId: managerTarget ?? input.selfId,
|
|
2233
|
+
self: { id: input.selfId, isManager: !managerTarget },
|
|
2234
|
+
manager: managerTarget ? { target: managerTarget, connected: connectedTo(input.sessions, managerTarget) } : { target: input.selfId, connected: true },
|
|
2235
|
+
coworkers: [],
|
|
2236
|
+
source: "standalone"
|
|
2237
|
+
};
|
|
2238
|
+
}
|
|
2158
2239
|
async function resolveIntercomTeam(input) {
|
|
2159
2240
|
const env = input.env ?? process.env;
|
|
2160
2241
|
const snapshot = await readWorkers(input.agentDir ?? getAgentDirPath());
|
|
2161
2242
|
const workers = snapshot.workers;
|
|
2162
2243
|
const workerId = stringValue(env.AGENT_INTERCOM_WORKER_ID);
|
|
2244
|
+
const selfSession = input.sessions.find((session) => session.id === input.selfId);
|
|
2245
|
+
const isBossContext = selfSession?.boss !== void 0 || hasBossEnvironmentKeys(env);
|
|
2163
2246
|
const bossIdentity = bossIdentityFromEnvironment(env);
|
|
2164
2247
|
const runId = stringValue(env.AGENT_INTERCOM_RUN_ID);
|
|
2165
|
-
|
|
2248
|
+
if (isBossContext && bossIdentity === void 0) {
|
|
2249
|
+
return {
|
|
2250
|
+
self: { id: input.selfId, ...workerId ? { workerId } : {}, isManager: false },
|
|
2251
|
+
coworkers: [],
|
|
2252
|
+
source: "boss"
|
|
2253
|
+
};
|
|
2254
|
+
}
|
|
2255
|
+
const currentMatches = workerId ? workers.filter((worker) => stringValue(worker.id) === workerId && (bossIdentity === void 0 ? snapshot.version === 1 && (!runId || stringValue(worker.runId) === runId) : snapshot.version === 2 && worker.canonicalIdentity?.workerId === bossIdentity.workerId && worker.canonicalIdentity.workerIncarnationId === bossIdentity.workerIncarnationId && worker.canonicalIdentity.workerGeneration === bossIdentity.workerGeneration && "bossRunId" in worker.canonicalIdentity && "bossRunId" in bossIdentity && worker.canonicalIdentity.bossRunId === bossIdentity.bossRunId && worker.canonicalIdentity.participantId === bossIdentity.participantId && worker.canonicalIdentity.bindingEpoch === bossIdentity.bindingEpoch)) : [];
|
|
2166
2256
|
const current = bossIdentity === void 0 ? currentMatches[0] : currentMatches.length === 1 ? currentMatches[0] : void 0;
|
|
2167
2257
|
const currentTarget = stringValue(current?.intercomTarget);
|
|
2168
2258
|
const exactCurrentProjection = current !== void 0 && currentTarget === input.selfId && workers.filter((worker) => stringValue(worker.id) === workerId).length === 1 && workers.filter((worker) => stringValue(worker.intercomTarget) === currentTarget).length === 1 && exactBossRosterSession(input.sessions, current) !== void 0;
|
|
2169
2259
|
if (bossIdentity !== void 0 && !exactCurrentProjection) {
|
|
2170
|
-
return { self: { id: input.selfId, ...workerId ? { workerId } : {}, isManager: false }, coworkers: [] };
|
|
2260
|
+
return { self: { id: input.selfId, ...workerId ? { workerId } : {}, isManager: false }, coworkers: [], source: "boss" };
|
|
2261
|
+
}
|
|
2262
|
+
if (bossIdentity === void 0 && !current) {
|
|
2263
|
+
if (workerId === void 0 && snapshot.version === 1) {
|
|
2264
|
+
const ownedCoworkers = workers.filter((worker) => worker.owned === true).filter((worker) => {
|
|
2265
|
+
const mgr = stringValue(worker.managerSessionId);
|
|
2266
|
+
return mgr !== void 0 && mgr === input.selfId;
|
|
2267
|
+
}).filter((worker) => LEGACY_LIVE_STATES.has(stringValue(worker.state) ?? "")).filter((worker) => stringValue(worker.id) !== input.selfId).map((worker) => {
|
|
2268
|
+
const id = stringValue(worker.id);
|
|
2269
|
+
if (!id) return void 0;
|
|
2270
|
+
const target = stringValue(worker.intercomTarget) ?? id;
|
|
2271
|
+
return {
|
|
2272
|
+
id,
|
|
2273
|
+
target,
|
|
2274
|
+
...stringValue(worker.harness) ? { harness: stringValue(worker.harness) } : {},
|
|
2275
|
+
...stringValue(worker.role) ? { role: stringValue(worker.role) } : {},
|
|
2276
|
+
...stringValue(worker.state) ? { state: stringValue(worker.state) } : {},
|
|
2277
|
+
connected: connectedTo(input.sessions, target)
|
|
2278
|
+
};
|
|
2279
|
+
}).filter((member) => Boolean(member));
|
|
2280
|
+
if (ownedCoworkers.length > 0) {
|
|
2281
|
+
return {
|
|
2282
|
+
teamId: input.selfId,
|
|
2283
|
+
self: { id: input.selfId, isManager: true },
|
|
2284
|
+
manager: { target: input.selfId, connected: true },
|
|
2285
|
+
coworkers: ownedCoworkers,
|
|
2286
|
+
source: "orchestrator"
|
|
2287
|
+
};
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2290
|
+
return resolveNonAuthoritativeTeam(input, env);
|
|
2171
2291
|
}
|
|
2172
|
-
const managerTarget = stringValue(current?.managerSessionId) ?? (bossIdentity === void 0 ? stringValue(env.AGENT_INTERCOM_MANAGER_TARGET) ?? stringValue(env.AGENT_INTERCOM_MANAGER_SESSION_ID) : void 0);
|
|
2173
|
-
const teamId = managerTarget ?? input.selfId;
|
|
2174
2292
|
const currentRole = stringValue(current?.role);
|
|
2293
|
+
const selfIsManager = bossIdentity !== void 0 ? currentRole === "manager" : void 0;
|
|
2294
|
+
const managerTarget = bossIdentity !== void 0 ? selfIsManager ? input.selfId : stringValue(current?.managerSessionId) : stringValue(current?.managerSessionId) ?? stringValue(env.AGENT_INTERCOM_MANAGER_TARGET) ?? stringValue(env.AGENT_INTERCOM_MANAGER_SESSION_ID);
|
|
2295
|
+
if (bossIdentity === void 0 && !managerTarget) {
|
|
2296
|
+
return {
|
|
2297
|
+
self: { id: input.selfId, ...workerId ? { workerId } : {}, isManager: false },
|
|
2298
|
+
coworkers: [],
|
|
2299
|
+
source: "orchestrator"
|
|
2300
|
+
};
|
|
2301
|
+
}
|
|
2302
|
+
const teamId = bossIdentity !== void 0 ? "bossRunId" in bossIdentity ? bossIdentity.bossRunId : managerTarget ?? input.selfId : managerTarget ?? input.selfId;
|
|
2175
2303
|
const canDiscoverOwnedRoster = bossIdentity === void 0 || currentRole === "manager" || currentRole === "controller";
|
|
2176
|
-
const coworkers = (canDiscoverOwnedRoster ? workers : []).filter((worker) => worker.owned === true).filter((worker) => bossIdentity === void 0 || snapshot.version === 2 && worker.canonicalIdentity !== void 0 && "bossRunId" in worker.canonicalIdentity && "bossRunId" in bossIdentity && worker.canonicalIdentity.bossRunId === bossIdentity.bossRunId).filter((worker) => stringValue(worker.managerSessionId) === teamId).filter((worker) => stringValue(worker.intercomTarget) !== managerTarget).filter((worker) => (snapshot.version === 2 ? CANONICAL_LIVE_STATES : LEGACY_LIVE_STATES).has(stringValue(worker.state) ?? "")).filter((worker) => stringValue(worker.id) !== workerId).map((worker) => {
|
|
2304
|
+
const coworkers = (canDiscoverOwnedRoster ? workers : []).filter((worker) => worker.owned === true).filter((worker) => bossIdentity === void 0 || snapshot.version === 2 && worker.canonicalIdentity !== void 0 && "bossRunId" in worker.canonicalIdentity && "bossRunId" in bossIdentity && worker.canonicalIdentity.bossRunId === bossIdentity.bossRunId).filter((worker) => stringValue(worker.managerSessionId) === (bossIdentity !== void 0 ? managerTarget : teamId)).filter((worker) => stringValue(worker.intercomTarget) !== managerTarget).filter((worker) => (snapshot.version === 2 ? CANONICAL_LIVE_STATES : LEGACY_LIVE_STATES).has(stringValue(worker.state) ?? "")).filter((worker) => stringValue(worker.id) !== workerId && stringValue(worker.id) !== input.selfId).map((worker) => {
|
|
2177
2305
|
const id = stringValue(worker.id);
|
|
2178
2306
|
if (!id) return void 0;
|
|
2179
2307
|
const target = stringValue(worker.intercomTarget) ?? id;
|
|
@@ -2190,11 +2318,13 @@ async function resolveIntercomTeam(input) {
|
|
|
2190
2318
|
}).filter((member) => Boolean(member));
|
|
2191
2319
|
const managerWorker = managerTarget === void 0 ? void 0 : workers.find((worker) => stringValue(worker.intercomTarget) === managerTarget && (bossIdentity === void 0 || snapshot.version === 2 && stringValue(worker.role) === "manager" && worker.canonicalIdentity !== void 0 && "bossRunId" in worker.canonicalIdentity && "bossRunId" in bossIdentity && worker.canonicalIdentity.bossRunId === bossIdentity.bossRunId));
|
|
2192
2320
|
const managerConnected = managerTarget === void 0 ? true : bossIdentity === void 0 ? connectedTo(input.sessions, managerTarget) : managerWorker !== void 0 && exactBossRosterSession(input.sessions, managerWorker) !== void 0;
|
|
2321
|
+
const isManager = bossIdentity !== void 0 ? selfIsManager : false;
|
|
2193
2322
|
return {
|
|
2194
2323
|
teamId,
|
|
2195
|
-
self: { id: input.selfId, ...workerId ? { workerId } : {}, isManager
|
|
2196
|
-
...managerTarget ? { manager: { target: managerTarget, connected:
|
|
2197
|
-
coworkers
|
|
2324
|
+
self: { id: input.selfId, ...workerId ? { workerId } : {}, isManager },
|
|
2325
|
+
...managerTarget ? { manager: { target: managerTarget, connected: isManager ? true : managerConnected } } : {},
|
|
2326
|
+
coworkers,
|
|
2327
|
+
source: bossIdentity !== void 0 ? "boss" : "orchestrator"
|
|
2198
2328
|
};
|
|
2199
2329
|
}
|
|
2200
2330
|
function formatIntercomTeam(team) {
|
|
@@ -2261,10 +2391,23 @@ function publicPendingEntry(entry, selector) {
|
|
|
2261
2391
|
function shortHash(value) {
|
|
2262
2392
|
return createHash3("sha256").update(value).digest("hex").slice(0, 8);
|
|
2263
2393
|
}
|
|
2394
|
+
var GENERIC_SESSION_ID_REGEX = /^[A-Za-z0-9_-]{1,128}$/;
|
|
2264
2395
|
function buildCodexRuntimeIdentity(env = process.env, cwd = env.PWD || processCwd(), pid = process.pid) {
|
|
2265
|
-
|
|
2396
|
+
let sessionId = env.CODEX_INTERCOM_SESSION_ID?.trim() || env.CODEX_PEER_ID?.trim();
|
|
2397
|
+
if (!sessionId && env.AGENT_INTERCOM_SESSION_ID !== void 0) {
|
|
2398
|
+
const raw = env.AGENT_INTERCOM_SESSION_ID.trim();
|
|
2399
|
+
if (raw) {
|
|
2400
|
+
if (!GENERIC_SESSION_ID_REGEX.test(raw)) {
|
|
2401
|
+
throw new Error("Invalid AGENT_INTERCOM_SESSION_ID: must match ^[A-Za-z0-9_-]{1,128}$");
|
|
2402
|
+
}
|
|
2403
|
+
sessionId = raw;
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
if (!sessionId) {
|
|
2407
|
+
sessionId = `codex-${pid}-${shortHash(cwd)}`;
|
|
2408
|
+
}
|
|
2266
2409
|
const cwdName = basename(cwd) || "workspace";
|
|
2267
|
-
const name = env.CODEX_INTERCOM_NAME?.trim() || env.CODEX_PEER_NAME?.trim() || `codex-${cwdName}-${pid}`;
|
|
2410
|
+
const name = env.CODEX_INTERCOM_NAME?.trim() || env.CODEX_PEER_NAME?.trim() || (env.AGENT_INTERCOM_SESSION_NAME !== void 0 && env.AGENT_INTERCOM_SESSION_NAME.trim() ? env.AGENT_INTERCOM_SESSION_NAME.trim() : void 0) || `codex-${cwdName}-${pid}`;
|
|
2268
2411
|
return {
|
|
2269
2412
|
sessionId,
|
|
2270
2413
|
name,
|
|
@@ -2330,7 +2473,8 @@ function detectGitRoot(cwd) {
|
|
|
2330
2473
|
const result = spawnSync("git", ["rev-parse", "--show-toplevel"], {
|
|
2331
2474
|
cwd,
|
|
2332
2475
|
encoding: "utf8",
|
|
2333
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
2476
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
2477
|
+
shell: false
|
|
2334
2478
|
});
|
|
2335
2479
|
if (result.status !== 0) return null;
|
|
2336
2480
|
return result.stdout.trim() || null;
|
|
@@ -2673,18 +2817,21 @@ function buildToolDefinitions(runtime2) {
|
|
|
2673
2817
|
name: "intercom_whoami",
|
|
2674
2818
|
description: "Return this Codex session's intercom identity for reliable targeting.",
|
|
2675
2819
|
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
2820
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
2676
2821
|
handler: async () => runtime2.whoami()
|
|
2677
2822
|
},
|
|
2678
2823
|
{
|
|
2679
2824
|
name: "intercom_team",
|
|
2680
2825
|
description: "Show your current manager and the live coworkers owned by that manager. No arguments are required.",
|
|
2681
2826
|
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
2827
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
2682
2828
|
handler: async () => runtime2.team()
|
|
2683
2829
|
},
|
|
2684
2830
|
{
|
|
2685
2831
|
name: "intercom_status",
|
|
2686
2832
|
description: "Show intercom connection status, active sessions, unread messages, and pending asks.",
|
|
2687
2833
|
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
2834
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
2688
2835
|
handler: async () => runtime2.status()
|
|
2689
2836
|
},
|
|
2690
2837
|
{
|
|
@@ -2698,6 +2845,7 @@ function buildToolDefinitions(runtime2) {
|
|
|
2698
2845
|
},
|
|
2699
2846
|
additionalProperties: false
|
|
2700
2847
|
},
|
|
2848
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
2701
2849
|
handler: async (args) => runtime2.list(
|
|
2702
2850
|
args.scope === "directory" || args.scope === "repo" ? args.scope : "machine",
|
|
2703
2851
|
asBoolean(args.include_self, false)
|
|
@@ -2712,6 +2860,7 @@ function buildToolDefinitions(runtime2) {
|
|
|
2712
2860
|
required: ["summary"],
|
|
2713
2861
|
additionalProperties: false
|
|
2714
2862
|
},
|
|
2863
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
|
|
2715
2864
|
handler: async (args) => runtime2.setSummary(asString(args.summary, "summary"))
|
|
2716
2865
|
},
|
|
2717
2866
|
{
|
|
@@ -2727,6 +2876,7 @@ function buildToolDefinitions(runtime2) {
|
|
|
2727
2876
|
required: ["to", "message"],
|
|
2728
2877
|
additionalProperties: false
|
|
2729
2878
|
},
|
|
2879
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
2730
2880
|
handler: async (args) => runtime2.send(asString(args.to, "to"), asString(args.message, "message"), asAttachmentArray(args.attachments))
|
|
2731
2881
|
},
|
|
2732
2882
|
{
|
|
@@ -2743,6 +2893,7 @@ function buildToolDefinitions(runtime2) {
|
|
|
2743
2893
|
required: ["to", "message"],
|
|
2744
2894
|
additionalProperties: false
|
|
2745
2895
|
},
|
|
2896
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
2746
2897
|
handler: async (args, signal) => runtime2.ask(
|
|
2747
2898
|
asString(args.to, "to"),
|
|
2748
2899
|
asString(args.message, "message"),
|
|
@@ -2759,6 +2910,7 @@ function buildToolDefinitions(runtime2) {
|
|
|
2759
2910
|
properties: { mark_read: { type: "boolean", default: false } },
|
|
2760
2911
|
additionalProperties: false
|
|
2761
2912
|
},
|
|
2913
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true },
|
|
2762
2914
|
handler: async (args) => runtime2.pending(asBoolean(args.mark_read, false))
|
|
2763
2915
|
},
|
|
2764
2916
|
{
|
|
@@ -2774,6 +2926,7 @@ function buildToolDefinitions(runtime2) {
|
|
|
2774
2926
|
required: ["message"],
|
|
2775
2927
|
additionalProperties: false
|
|
2776
2928
|
},
|
|
2929
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
|
2777
2930
|
handler: async (args) => runtime2.reply(asString(args.message, "message"), typeof args.to === "string" ? args.to : void 0, args.which === "oldest" || args.which === "latest" ? args.which : void 0)
|
|
2778
2931
|
}
|
|
2779
2932
|
];
|
|
@@ -2810,7 +2963,7 @@ async function handleMcpRequest(request, runtime2) {
|
|
|
2810
2963
|
return ok(request.id, {});
|
|
2811
2964
|
case "tools/list":
|
|
2812
2965
|
return ok(request.id, {
|
|
2813
|
-
tools: tools.map(({ name, description, inputSchema }) => ({ name, description, inputSchema }))
|
|
2966
|
+
tools: tools.map(({ name, description, inputSchema, annotations }) => ({ name, description, inputSchema, annotations }))
|
|
2814
2967
|
});
|
|
2815
2968
|
case "tools/call": {
|
|
2816
2969
|
const name = request.params?.name;
|