ticlawk 0.1.16-dev.19 → 0.1.16-dev.20
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/package.json
CHANGED
|
@@ -126,7 +126,7 @@ ${buildGoalSetupRules()}
|
|
|
126
126
|
4. Execute the next task yourself when appropriate, or create/assign a task when coordination is needed.
|
|
127
127
|
5. Check whether the result closes the gap.
|
|
128
128
|
6. Return to evaluating current facts against the goal.
|
|
129
|
-
- During each goal-loop iteration, explicitly write a private loop check before acting: current facts, goal/success criterion, gap, next action, and stop/continue decision. This is for your execution discipline, not a chat message. Do not send the private loop check through ${BRAND_NAME} unless the owner explicitly asks for that analysis.
|
|
129
|
+
- During each goal-loop iteration, explicitly write a private loop check before acting: current facts, goal/success criterion, gap, next action, and stop/continue decision. Treat tool calls, file edits, task updates, dashboard/briefing writes, and \`ticlawk message send\` as actions. This is for your execution discipline, not a chat message. Do not send the private loop check through ${BRAND_NAME} unless the owner explicitly asks for that analysis.
|
|
130
130
|
- Stop the loop only when there is no meaningful gap, progress is blocked because the owner needs to provide input/resources/permission/confirmation/decision, or progress depends on an external/time-based wait.
|
|
131
131
|
- If there is no gap, say so briefly. If the goal is complete, report completion.
|
|
132
132
|
- If user input, resources, permission, confirmation, or a decision is needed, publish a briefing with one clear bundled request to the owner.
|
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
* and discover local sessions.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { createHash } from 'node:crypto';
|
|
9
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
10
|
+
import { homedir } from 'node:os';
|
|
11
|
+
import { basename, join } from 'node:path';
|
|
9
12
|
import {
|
|
10
13
|
createCodexSession,
|
|
11
14
|
runCodexPrompt,
|
|
@@ -32,6 +35,84 @@ import {
|
|
|
32
35
|
import { buildAgentRuntimeEnv } from '../../core/runtime-env.mjs';
|
|
33
36
|
import { buildStandingPrompt } from '../_shared/standing-prompt.mjs';
|
|
34
37
|
import { ensureAgentHome } from '../../core/agent-home.mjs';
|
|
38
|
+
import { debugError, debugLog } from '../../core/logger.mjs';
|
|
39
|
+
|
|
40
|
+
function parseBooleanish(value) {
|
|
41
|
+
if (value === undefined || value === null || value === '') return false;
|
|
42
|
+
return ['1', 'true', 'on', 'yes'].includes(String(value).trim().toLowerCase());
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function sha256(text) {
|
|
46
|
+
return createHash('sha256').update(String(text || ''), 'utf8').digest('hex');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function fileSafeId(value) {
|
|
50
|
+
return String(value || 'unknown')
|
|
51
|
+
.replace(/[^a-zA-Z0-9_-]+/g, '-')
|
|
52
|
+
.replace(/^-+|-+$/g, '')
|
|
53
|
+
.slice(0, 80) || 'unknown';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function writePromptSnapshot({
|
|
57
|
+
binding,
|
|
58
|
+
inbound,
|
|
59
|
+
agentHome,
|
|
60
|
+
targetSessionId,
|
|
61
|
+
shouldRotate,
|
|
62
|
+
developerInstructions,
|
|
63
|
+
message,
|
|
64
|
+
input,
|
|
65
|
+
}) {
|
|
66
|
+
if (!parseBooleanish(process.env.TICLAWK_LOG_RUNTIME_PROMPTS)) return;
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const rootDir = process.env.TICLAWK_RUNTIME_PROMPT_LOG_DIR
|
|
70
|
+
|| join(homedir(), '.ticlawk', 'prompt-logs');
|
|
71
|
+
const dir = join(rootDir, fileSafeId(binding?.id));
|
|
72
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
73
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
74
|
+
const messageId = fileSafeId(inbound?.messageId);
|
|
75
|
+
const filePath = join(dir, `${stamp}-${messageId}.json`);
|
|
76
|
+
const payload = {
|
|
77
|
+
createdAt: new Date().toISOString(),
|
|
78
|
+
runtime: 'codex',
|
|
79
|
+
agentId: binding?.id || null,
|
|
80
|
+
conversationId: inbound?.conversationId || null,
|
|
81
|
+
messageId: inbound?.messageId || null,
|
|
82
|
+
target: inbound?.envelopeTarget || null,
|
|
83
|
+
action: inbound?.action || null,
|
|
84
|
+
sessionId: targetSessionId || null,
|
|
85
|
+
shouldRotate: Boolean(shouldRotate),
|
|
86
|
+
agentHome,
|
|
87
|
+
hashes: {
|
|
88
|
+
developerInstructionsSha256: sha256(developerInstructions),
|
|
89
|
+
messageSha256: sha256(message),
|
|
90
|
+
},
|
|
91
|
+
developerInstructions,
|
|
92
|
+
message,
|
|
93
|
+
input: input || null,
|
|
94
|
+
};
|
|
95
|
+
writeFileSync(filePath, `${JSON.stringify(payload, null, 2)}\n`, { mode: 0o600 });
|
|
96
|
+
debugLog('codex', 'prompt.snapshot', {
|
|
97
|
+
agentId: binding?.id,
|
|
98
|
+
conversationId: inbound?.conversationId,
|
|
99
|
+
messageId: inbound?.messageId,
|
|
100
|
+
target: inbound?.envelopeTarget,
|
|
101
|
+
path: filePath,
|
|
102
|
+
developerInstructionChars: String(developerInstructions || '').length,
|
|
103
|
+
messageChars: String(message || '').length,
|
|
104
|
+
developerInstructionsSha256: payload.hashes.developerInstructionsSha256,
|
|
105
|
+
messageSha256: payload.hashes.messageSha256,
|
|
106
|
+
});
|
|
107
|
+
} catch (err) {
|
|
108
|
+
debugError('codex', 'prompt.snapshot.failed', {
|
|
109
|
+
agentId: binding?.id,
|
|
110
|
+
conversationId: inbound?.conversationId,
|
|
111
|
+
messageId: inbound?.messageId,
|
|
112
|
+
error: err?.message || String(err),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
35
116
|
|
|
36
117
|
export const codexRuntime = {
|
|
37
118
|
name: 'codex',
|
|
@@ -176,6 +257,16 @@ export const codexRuntime = {
|
|
|
176
257
|
target: inbound.envelopeTarget,
|
|
177
258
|
});
|
|
178
259
|
const developerInstructions = buildStandingPrompt({ agentId: binding.id, inbound });
|
|
260
|
+
writePromptSnapshot({
|
|
261
|
+
binding,
|
|
262
|
+
inbound,
|
|
263
|
+
agentHome,
|
|
264
|
+
targetSessionId,
|
|
265
|
+
shouldRotate,
|
|
266
|
+
developerInstructions,
|
|
267
|
+
message,
|
|
268
|
+
input: codexInput,
|
|
269
|
+
});
|
|
179
270
|
const result = (shouldRotate || inbound.action === 'image' || shouldStreamRuntime(this.name, this))
|
|
180
271
|
? await this.runTurnStream({ sessionId: targetSessionId, cwd: agentHome, codexPath: runtimeCodexPath, agentEnv }, message, {
|
|
181
272
|
input: codexInput,
|