Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 0 additions & 178 deletions lib/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { homedir } from "os"
export class Logger {
private logDir: string
public enabled: boolean
private fileCounter: number = 0

constructor(enabled: boolean) {
this.enabled = enabled
Expand Down Expand Up @@ -109,181 +108,4 @@ export class Logger {
const component = this.getCallerFile(2)
return this.write("ERROR", component, message, data)
}

private parseJanitorPrompt(prompt: string): {
instructions: string
availableToolCallIds: string[]
sessionHistory: any[]
responseSchema: any
} | null {
try {
const idsMatch = prompt.match(/Available tool call IDs for analysis:\s*([^\n]+)/)
const availableToolCallIds = idsMatch
? idsMatch[1].split(',').map(id => id.trim())
: []

const historyMatch = prompt.match(/Session history[^\n]*:\s*\n([\s\S]*?)\n\nYou MUST respond/)
let sessionHistory: any[] = []

if (historyMatch) {
const historyText = historyMatch[1]

const fixedJson = this.escapeNewlinesInJson(historyText)
sessionHistory = JSON.parse(fixedJson)
}

const instructionsMatch = prompt.match(/([\s\S]*?)\n\nIMPORTANT: Available tool call IDs/)
const instructions = instructionsMatch
? instructionsMatch[1].trim()
: ''

const schemaMatch = prompt.match(/matching this exact schema:\s*\n(\{[\s\S]*?\})\s*$/)
const responseSchema = schemaMatch
? schemaMatch[1]
: null

return {
instructions,
availableToolCallIds,
sessionHistory,
responseSchema
}
} catch (error) {
return null
}
}

private escapeNewlinesInJson(jsonText: string): string {
let result = ''
let inString = false

for (let i = 0; i < jsonText.length; i++) {
const char = jsonText[i]
const prevChar = i > 0 ? jsonText[i - 1] : ''

if (char === '"' && prevChar !== '\\') {
inString = !inString
result += char
} else if (char === '\n' && inString) {
result += '\\n'
} else {
result += char
}
}

return result
}

private extractReasoningBlocks(sessionMessages: any[]): any[] {
const reasoningBlocks: any[] = []

for (const msg of sessionMessages) {
if (!msg.parts) continue

for (const part of msg.parts) {
if (part.type === "reasoning") {
// Calculate encrypted content size for different providers
let encryptedContentLength = 0
if (part.metadata?.openai?.reasoningEncryptedContent) {
encryptedContentLength = part.metadata.openai.reasoningEncryptedContent.length
} else if (part.metadata?.anthropic?.signature) {
encryptedContentLength = part.metadata.anthropic.signature.length
} else if (part.metadata?.google?.thoughtSignature) {
encryptedContentLength = part.metadata.google.thoughtSignature.length
}

reasoningBlocks.push({
messageId: msg.id,
messageRole: msg.role,
text: part.text,
textLength: part.text?.length || 0,
encryptedContentLength,
time: part.time,
hasMetadata: !!part.metadata,
metadataKeys: part.metadata ? Object.keys(part.metadata) : []
})
}
}
}

return reasoningBlocks
}

async saveWrappedContext(sessionID: string, messages: any[], metadata: any, sessionMessages?: any[]) {
if (!this.enabled) return

try {
await this.ensureLogDir()

const aiContextDir = join(this.logDir, "ai-context")
if (!existsSync(aiContextDir)) {
await mkdir(aiContextDir, { recursive: true })
}

const timestamp = new Date().toISOString().replace(/:/g, '-').replace(/\./g, '-')
const counter = (this.fileCounter++).toString().padStart(3, '0')
const filename = `${timestamp}_${counter}_${sessionID.substring(0, 15)}.json`
const filepath = join(aiContextDir, filename)

const isJanitorShadow = sessionID === "janitor-shadow" &&
messages.length === 1 &&
messages[0]?.role === 'user' &&
typeof messages[0]?.content === 'string'

let content: any

if (isJanitorShadow) {
const parsed = this.parseJanitorPrompt(messages[0].content)

if (parsed) {
content = {
timestamp: new Date().toISOString(),
sessionID,
metadata,
janitorAnalysis: {
instructions: parsed.instructions,
availableToolCallIds: parsed.availableToolCallIds,
protectedTools: ["task", "todowrite", "todoread"],
sessionHistory: parsed.sessionHistory,
responseSchema: parsed.responseSchema
},
rawPrompt: messages[0].content
}
} else {
content = {
timestamp: new Date().toISOString(),
sessionID,
metadata,
messages,
note: "Failed to parse janitor prompt structure"
}
}
} else {
// Extract reasoning blocks from session messages if available
const reasoningBlocks = sessionMessages
? this.extractReasoningBlocks(sessionMessages)
: []

content = {
timestamp: new Date().toISOString(),
sessionID,
metadata,
messages,
...(reasoningBlocks.length > 0 && {
reasoning: {
count: reasoningBlocks.length,
totalTextCharacters: reasoningBlocks.reduce((sum, b) => sum + b.textLength, 0),
totalEncryptedCharacters: reasoningBlocks.reduce((sum, b) => sum + b.encryptedContentLength, 0),
blocks: reasoningBlocks
}
})
}
}

const jsonString = JSON.stringify(content, null, 2)

await writeFile(filepath, jsonString)
} catch (error) {
}
}
}