replicas-engine 0.1.9 → 0.1.10

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.
@@ -38,18 +38,13 @@ export class CodexManager {
38
38
  else {
39
39
  console.log('[CodexManager] No existing thread, starting new thread');
40
40
  console.log(`[CodexManager] Working directory: ${this.workingDirectory}`);
41
- this.currentThread = this.codex.startThread({
41
+ const thread = this.codex.startThread({
42
42
  workingDirectory: this.workingDirectory,
43
43
  skipGitRepoCheck: true,
44
44
  sandboxMode: 'danger-full-access',
45
45
  });
46
- if (this.currentThread.id) {
47
- this.currentThreadId = this.currentThread.id;
48
- console.log(`[CodexManager] New thread created with ID: ${this.currentThreadId}`);
49
- }
50
- else {
51
- console.error('[CodexManager] ERROR: Thread created but no ID available');
52
- }
46
+ this.currentThread = thread;
47
+ console.log(`[CodexManager] Thread object created, ID at creation: ${thread.id || 'null'}`);
53
48
  // prime the thread with system instructions if thread is new
54
49
  const workspaceName = process.env.WORKSPACE_NAME || 'workspace';
55
50
  console.log(`[CodexManager] Workspace name from env: ${workspaceName}`);
@@ -64,9 +59,27 @@ export class CodexManager {
64
59
  const systemMessage = `<replicas_important_instructions>When completing solutions, push your changes to branch ${branchName} and to origin. Greet the user.</replicas_important_instructions>`;
65
60
  console.log('[CodexManager] Starting thread priming with system instructions');
66
61
  const primingStartTime = Date.now();
67
- await this.currentThread.run(systemMessage);
62
+ // Use runStreamed to capture thread.started event with thread_id
63
+ const streamedTurn = await this.currentThread.runStreamed(systemMessage);
64
+ console.log('[CodexManager] Processing priming stream events...');
65
+ for await (const event of streamedTurn.events) {
66
+ console.log(`[CodexManager] Event: ${event.type}`);
67
+ if (event.type === 'thread.started') {
68
+ this.currentThreadId = event.thread_id;
69
+ console.log(`[CodexManager] ✓ Thread ID captured from thread.started event: ${this.currentThreadId}`);
70
+ }
71
+ }
68
72
  const primingDuration = Date.now() - primingStartTime;
69
73
  console.log(`[CodexManager] Thread priming completed in ${primingDuration}ms`);
74
+ // Double-check thread ID is available
75
+ if (!this.currentThreadId && this.currentThread.id) {
76
+ this.currentThreadId = this.currentThread.id;
77
+ console.log(`[CodexManager] Thread ID fallback from thread.id property: ${this.currentThreadId}`);
78
+ }
79
+ if (!this.currentThreadId) {
80
+ console.error('[CodexManager] ERROR: Thread ID still not available after priming run');
81
+ console.error(`[CodexManager] thread.id = ${this.currentThread.id}`);
82
+ }
70
83
  }
71
84
  }
72
85
  else {
@@ -2,30 +2,36 @@ import { readFile, readdir, stat } from 'fs/promises';
2
2
  import { join } from 'path';
3
3
  import { homedir } from 'os';
4
4
  export async function readJSONL(filePath) {
5
+ console.log(`[jsonl-reader] readJSONL called for: ${filePath}`);
5
6
  try {
6
7
  const content = await readFile(filePath, 'utf-8');
7
- return content
8
- .split('\n')
9
- .filter((line) => line.trim())
10
- .map((line) => {
8
+ console.log(`[jsonl-reader] File read successfully, content length: ${content.length} bytes`);
9
+ const lines = content.split('\n').filter((line) => line.trim());
10
+ console.log(`[jsonl-reader] Found ${lines.length} non-empty lines`);
11
+ const events = lines
12
+ .map((line, index) => {
11
13
  try {
12
14
  return JSON.parse(line);
13
15
  }
14
16
  catch (e) {
15
- console.error(`Failed to parse JSONL line: ${line}`, e);
17
+ console.error(`[jsonl-reader] Failed to parse line ${index + 1}: ${line.substring(0, 100)}...`, e);
16
18
  return null;
17
19
  }
18
20
  })
19
21
  .filter((event) => event !== null);
22
+ console.log(`[jsonl-reader] Successfully parsed ${events.length} events`);
23
+ return events;
20
24
  }
21
25
  catch (error) {
22
- console.error(`Failed to read JSONL file ${filePath}:`, error);
26
+ console.error(`[jsonl-reader] ERROR: Failed to read JSONL file ${filePath}:`, error);
23
27
  return [];
24
28
  }
25
29
  }
26
30
  // Sessions are stored in ~/.codex/sessions/YYYY/MM/DD/rollout-*-{threadId}.jsonl
27
31
  export async function findSessionFile(threadId) {
32
+ console.log(`[jsonl-reader] findSessionFile called for threadId: ${threadId}`);
28
33
  const sessionsDir = join(homedir(), '.codex', 'sessions');
34
+ console.log(`[jsonl-reader] Sessions directory: ${sessionsDir}`);
29
35
  try {
30
36
  // current date for searching
31
37
  const now = new Date();
@@ -33,9 +39,13 @@ export async function findSessionFile(threadId) {
33
39
  const month = String(now.getMonth() + 1).padStart(2, '0');
34
40
  const day = String(now.getDate()).padStart(2, '0');
35
41
  const todayDir = join(sessionsDir, String(year), month, day);
42
+ console.log(`[jsonl-reader] Searching today's directory: ${todayDir}`);
36
43
  const file = await findFileInDirectory(todayDir, threadId);
37
- if (file)
44
+ if (file) {
45
+ console.log(`[jsonl-reader] Found file in today's directory: ${file}`);
38
46
  return file;
47
+ }
48
+ console.log(`[jsonl-reader] Not found in today's directory, searching previous 7 days`);
39
49
  for (let daysAgo = 1; daysAgo <= 7; daysAgo++) {
40
50
  const date = new Date(now);
41
51
  date.setDate(date.getDate() - daysAgo);
@@ -43,32 +53,47 @@ export async function findSessionFile(threadId) {
43
53
  const searchMonth = String(date.getMonth() + 1).padStart(2, '0');
44
54
  const searchDay = String(date.getDate()).padStart(2, '0');
45
55
  const searchDir = join(sessionsDir, String(searchYear), searchMonth, searchDay);
56
+ console.log(`[jsonl-reader] Searching ${daysAgo} day(s) ago: ${searchDir}`);
46
57
  const file = await findFileInDirectory(searchDir, threadId);
47
- if (file)
58
+ if (file) {
59
+ console.log(`[jsonl-reader] Found file ${daysAgo} day(s) ago: ${file}`);
48
60
  return file;
61
+ }
49
62
  }
63
+ console.log(`[jsonl-reader] Session file not found after searching 8 days`);
50
64
  return null;
51
65
  }
52
66
  catch (error) {
53
- console.error('Error finding session file:', error);
67
+ console.error('[jsonl-reader] ERROR finding session file:', error);
54
68
  return null;
55
69
  }
56
70
  }
57
71
  async function findFileInDirectory(directory, threadId) {
58
72
  try {
73
+ console.log(`[jsonl-reader] Reading directory: ${directory}`);
59
74
  const files = await readdir(directory);
75
+ console.log(`[jsonl-reader] Found ${files.length} files in directory`);
76
+ const jsonlFiles = files.filter(f => f.endsWith('.jsonl'));
77
+ console.log(`[jsonl-reader] ${jsonlFiles.length} JSONL files: ${jsonlFiles.join(', ')}`);
60
78
  for (const file of files) {
61
79
  if (file.endsWith('.jsonl') && file.includes(threadId)) {
62
80
  const fullPath = join(directory, file);
81
+ console.log(`[jsonl-reader] Found matching file: ${file} -> ${fullPath}`);
63
82
  const stats = await stat(fullPath);
64
83
  if (stats.isFile()) {
84
+ console.log(`[jsonl-reader] Confirmed as regular file, returning: ${fullPath}`);
65
85
  return fullPath;
66
86
  }
87
+ else {
88
+ console.log(`[jsonl-reader] WARNING: Path exists but is not a regular file`);
89
+ }
67
90
  }
68
91
  }
92
+ console.log(`[jsonl-reader] No matching file found in ${directory}`);
69
93
  return null;
70
94
  }
71
95
  catch (error) {
96
+ console.log(`[jsonl-reader] Directory read failed for ${directory}:`, error instanceof Error ? error.message : error);
72
97
  return null;
73
98
  }
74
99
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",