@canonmsg/codex-plugin 0.9.3 → 0.9.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/host.js +32 -5
- package/package.json +2 -2
package/dist/host.js
CHANGED
|
@@ -3,7 +3,7 @@ import { setDefaultResultOrder } from 'node:dns';
|
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
4
|
import { parseArgs } from 'node:util';
|
|
5
5
|
import { getCodexImagePath, materializeMessageMedia, } from '@canonmsg/agent-sdk';
|
|
6
|
-
import { buildCanonHostPrompt, buildConfiguredWorkspaceOptionsWithRoots, buildFirstPartyCodingRuntimeDescriptor, buildHydratedInboundContext, buildPublicWorkspaceRoots, buildPublicWorkspaceOptions, createConversationMetadataLoader, createRuntimeStatePublisher, EXECUTION_ENVIRONMENT_MODES, ExecutionEnvironmentError, CanonClient, CanonStream, DEFAULT_PARTICIPATION_HISTORY_FETCH_LIMIT, DEFAULT_RUNTIME_CAPABILITIES, FINAL_MESSAGE_HANDOFF_MS, getActiveProfileLock, initRTDBAuth, buildLocalRuntimeId, heartbeatLocalRuntimeEntry, loadRuntimeSessionState, markLocalRuntimeStopped, normalizeTurnMetadata, normalizeTurnState, prepareConversationEnvironment, loadHostSessionConfig, releaseConversationEnvironment, resolveCanonAgent, rtdbRead, shouldTriggerAgentTurn, saveRuntimeSessionState, publishHostAgentRuntime, publishHostSessionSnapshots, renderCanonHostInboundContent, resolveHostWorkspaceCwd, upsertLocalRuntimeEntry, } from '@canonmsg/core';
|
|
6
|
+
import { buildCanonHostPrompt, buildConfiguredWorkspaceOptionsWithRoots, buildFirstPartyCodingRuntimeDescriptor, buildHydratedInboundContext, buildPublicWorkspaceRoots, buildPublicWorkspaceOptions, createConversationMetadataLoader, createRuntimeStatePublisher, EXECUTION_ENVIRONMENT_MODES, ExecutionEnvironmentError, CanonClient, CanonStream, DEFAULT_PARTICIPATION_HISTORY_FETCH_LIMIT, DEFAULT_RUNTIME_CAPABILITIES, FINAL_MESSAGE_HANDOFF_MS, getActiveProfileLock, initRTDBAuth, buildLocalRuntimeId, heartbeatLocalRuntimeEntry, loadRuntimeSessionState, markLocalRuntimeStopped, normalizeTurnMetadata, normalizeTurnState, prepareConversationEnvironment, loadHostSessionConfig, releaseConversationEnvironment, resolveCanonAgent, rtdbRead, rtdbWrite, shouldTriggerAgentTurn, saveRuntimeSessionState, publishHostAgentRuntime, publishHostSessionSnapshots, renderCanonHostInboundContent, resolveHostWorkspaceCwd, upsertLocalRuntimeEntry, } from '@canonmsg/core';
|
|
7
7
|
import { buildInboundContextLines, decideAutoReply, } from './inbound-policy.js';
|
|
8
8
|
import { CodexConversationAdapter, } from './adapter.js';
|
|
9
9
|
import { clearStoredThreadId, loadStoredThreadId, saveStoredThreadId, } from './session-store.js';
|
|
@@ -295,6 +295,13 @@ export async function main() {
|
|
|
295
295
|
return;
|
|
296
296
|
await client.updateMessageDisposition(conversationId, sourceMessageId, 'accepted_now').catch(() => { });
|
|
297
297
|
}
|
|
298
|
+
async function markQueuedPromptsRejected(conversationId, prompts) {
|
|
299
|
+
await Promise.all(prompts.map((prompt) => {
|
|
300
|
+
if (!prompt.markAccepted || !prompt.sourceMessageId)
|
|
301
|
+
return Promise.resolve();
|
|
302
|
+
return client.updateMessageDisposition(conversationId, prompt.sourceMessageId, 'rejected').catch(() => { });
|
|
303
|
+
}));
|
|
304
|
+
}
|
|
298
305
|
function clearStreaming(conversationId) {
|
|
299
306
|
runtimeState.clearStreaming(conversationId).catch(() => { });
|
|
300
307
|
}
|
|
@@ -421,6 +428,7 @@ export async function main() {
|
|
|
421
428
|
closed: false,
|
|
422
429
|
};
|
|
423
430
|
sessions.set(conversationId, session);
|
|
431
|
+
await baselineControlSignal(conversationId);
|
|
424
432
|
console.error(`[canon-codex] [${conversationId.slice(0, 8)}] Environment → ${environment.mode} (${sessionCwd})`);
|
|
425
433
|
writeState(session);
|
|
426
434
|
writeTurn(session);
|
|
@@ -663,6 +671,8 @@ export async function main() {
|
|
|
663
671
|
}
|
|
664
672
|
}
|
|
665
673
|
let controlStopped = false;
|
|
674
|
+
const lastSeenControl = new Map();
|
|
675
|
+
const lastSeenSignal = new Map();
|
|
666
676
|
let streamConnected = false;
|
|
667
677
|
const hostAvailableExecutionModes = [
|
|
668
678
|
...EXECUTION_ENVIRONMENT_MODES,
|
|
@@ -686,6 +696,17 @@ export async function main() {
|
|
|
686
696
|
defaultPermissionMode: codexPermissionEnvelope.defaultPermissionMode,
|
|
687
697
|
}),
|
|
688
698
|
};
|
|
699
|
+
async function baselineControlSignal(conversationId) {
|
|
700
|
+
if (lastSeenSignal.has(conversationId))
|
|
701
|
+
return;
|
|
702
|
+
const raw = await rtdbRead(`/control/${conversationId}/${agentId}/signal`).catch(() => null);
|
|
703
|
+
if (!raw || typeof raw !== 'object')
|
|
704
|
+
return;
|
|
705
|
+
const timestamp = Number(raw.updatedAt ?? 0);
|
|
706
|
+
if (timestamp > 0) {
|
|
707
|
+
lastSeenSignal.set(conversationId, timestamp);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
689
710
|
const publishRuntimeHeartbeat = async () => {
|
|
690
711
|
heartbeatLocalRuntimeEntry(runtimeId, {
|
|
691
712
|
agentId,
|
|
@@ -914,8 +935,6 @@ export async function main() {
|
|
|
914
935
|
await stream.start().catch((error) => {
|
|
915
936
|
console.error('[canon-codex] SSE start error:', error instanceof Error ? error.message : error);
|
|
916
937
|
});
|
|
917
|
-
const lastSeenControl = new Map();
|
|
918
|
-
const lastSeenSignal = new Map();
|
|
919
938
|
const pollControl = async () => {
|
|
920
939
|
while (!controlStopped) {
|
|
921
940
|
for (const conversationId of [...sessions.keys()]) {
|
|
@@ -956,15 +975,23 @@ export async function main() {
|
|
|
956
975
|
const session = sessions.get(conversationId);
|
|
957
976
|
if (!session || session.closed)
|
|
958
977
|
continue;
|
|
978
|
+
if (!session.running && (signal.type !== 'stop_and_drop' || session.queue.length === 0)) {
|
|
979
|
+
await rtdbWrite(`/control/${conversationId}/${agentId}/signal`, null).catch(() => { });
|
|
980
|
+
continue;
|
|
981
|
+
}
|
|
959
982
|
console.error(`[canon-codex] [${conversationId.slice(0, 8)}] ${signal.type} signal`);
|
|
960
|
-
|
|
983
|
+
if (session.running) {
|
|
984
|
+
await session.adapter.interrupt();
|
|
985
|
+
}
|
|
961
986
|
session.turnState = 'interrupted';
|
|
962
987
|
if (signal.type === 'stop_and_drop') {
|
|
963
|
-
session.queue.
|
|
988
|
+
const droppedPrompts = session.queue.splice(0);
|
|
989
|
+
await markQueuedPromptsRejected(conversationId, droppedPrompts);
|
|
964
990
|
}
|
|
965
991
|
writeTurn(session);
|
|
966
992
|
clearStreaming(conversationId);
|
|
967
993
|
client.setTyping(conversationId, false).catch(() => { });
|
|
994
|
+
await rtdbWrite(`/control/${conversationId}/${agentId}/signal`, null).catch(() => { });
|
|
968
995
|
}
|
|
969
996
|
catch {
|
|
970
997
|
// Ignore transient RTDB failures.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonmsg/codex-plugin",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
4
4
|
"description": "Canon host integration for Codex CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"prepack": "npm run build"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@canonmsg/agent-sdk": "^1.
|
|
32
|
+
"@canonmsg/agent-sdk": "^1.1.0",
|
|
33
33
|
"@canonmsg/core": "^0.15.0"
|
|
34
34
|
},
|
|
35
35
|
"engines": {
|