mirror of
https://github.com/thedotmack/claude-mem
synced 2026-04-25 17:15:04 +02:00
Release v5.1.3: Fix PostToolUse hook field name bug
Bug Fix: - Changed tool_output to tool_response throughout PostToolUse hook chain - PostToolUse events provide tool_response field, not tool_output - Updated save-hook.ts to send tool_response - Updated worker-service.ts endpoint to accept tool_response - Updated worker-service-v2.ts for consistency - Updated worker-types.ts interfaces (PendingMessage, ObservationData) - Updated SessionManager.ts message queue - Updated SDKAgent.ts observation prompt builder Impact: Fixes observation capture for PostToolUse events. Previous version was sending undefined for tool responses, causing incomplete observations. Files changed: - src/hooks/save-hook.ts (interface + destructuring + fetch body) - src/services/worker-service.ts (ObservationMessage interface + handler + SDK prompt) - src/services/worker-service-v2.ts (handler) - src/services/worker-types.ts (PendingMessage + ObservationData interfaces) - src/services/worker/SessionManager.ts (queue push) - src/services/worker/SDKAgent.ts (observation prompt) - plugin/scripts/*.js (rebuilt) - Version bumped to 5.1.3 (patch) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
"plugins": [
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"version": "5.1.2",
|
||||
"version": "5.1.3",
|
||||
"source": "./plugin",
|
||||
"description": "Persistent memory system for Claude Code - context compression across sessions"
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ Claude-mem is a Claude Code plugin providing persistent memory across sessions.
|
||||
|
||||
**Your Role**: You are working on the plugin itself. When users interact with Claude Code with this plugin installed, your observations get captured and become their persistent memory.
|
||||
|
||||
**Current Version**: 5.1.2
|
||||
**Current Version**: 5.1.3
|
||||
|
||||
## Critical Architecture Knowledge
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"version": "5.1.2",
|
||||
"version": "5.1.3",
|
||||
"description": "Memory compression system for Claude Code - persist context across sessions",
|
||||
"keywords": [
|
||||
"claude",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"version": "5.1.2",
|
||||
"version": "5.1.3",
|
||||
"description": "Persistent memory system for Claude Code - seamlessly preserve context across sessions",
|
||||
"author": {
|
||||
"name": "Alex Newman"
|
||||
|
||||
@@ -400,4 +400,4 @@ ${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let s=Obje
|
||||
JOIN sdk_sessions s ON up.claude_session_id = s.claude_session_id
|
||||
WHERE up.created_at_epoch >= ? AND up.created_at_epoch <= ? ${o.replace("project","s.project")}
|
||||
ORDER BY up.created_at_epoch ASC
|
||||
`;try{let T=this.db.prepare(c).all(p,u,...i),S=this.db.prepare(m).all(p,u,...i),_=this.db.prepare(g).all(p,u,...i);return{observations:T,sessions:S.map(d=>({id:d.id,sdk_session_id:d.sdk_session_id,project:d.project,request:d.request,completed:d.completed,next_steps:d.next_steps,created_at:d.created_at,created_at_epoch:d.created_at_epoch})),prompts:_.map(d=>({id:d.id,claude_session_id:d.claude_session_id,project:d.project,prompt:d.prompt_text,created_at:d.created_at,created_at_epoch:d.created_at_epoch}))}}catch(T){return console.error("[SessionStore] Error querying timeline records:",T.message),{observations:[],sessions:[],prompts:[]}}}close(){this.db.close()}};function $(a,e,s){return a==="PreCompact"?e?{continue:!0,suppressOutput:!0}:{continue:!1,stopReason:s.reason||"Pre-compact operation failed",suppressOutput:!0}:a==="SessionStart"?e&&s.context?{continue:!0,suppressOutput:!0,hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:s.context}}:{continue:!0,suppressOutput:!0}:a==="UserPromptSubmit"||a==="PostToolUse"?{continue:!0,suppressOutput:!0}:a==="Stop"?{continue:!0,suppressOutput:!0}:{continue:e,suppressOutput:!0,...s.reason&&!e?{stopReason:s.reason}:{}}}function f(a,e,s={}){let t=$(a,e,s);return JSON.stringify(t)}import I from"path";import{homedir as W}from"os";import{existsSync as G,readFileSync as Y}from"fs";import{execSync as K}from"child_process";var V=100,q=100,J=1e4;function L(){try{let a=I.join(W(),".claude-mem","settings.json");if(G(a)){let e=JSON.parse(Y(a,"utf-8")),s=parseInt(e.env?.CLAUDE_MEM_WORKER_PORT,10);if(!isNaN(s))return s}}catch{}return parseInt(process.env.CLAUDE_MEM_WORKER_PORT||"37777",10)}async function k(){try{let a=L();return(await fetch(`http://127.0.0.1:${a}/health`,{signal:AbortSignal.timeout(V)})).ok}catch{return!1}}async function Q(){let a=Date.now();for(;Date.now()-a<J;){if(await k())return!0;await new Promise(e=>setTimeout(e,q))}return!1}async function x(){if(await k())return;let a=D(),e=I.join(a,"node_modules",".bin","pm2"),s=I.join(a,"ecosystem.config.cjs");if(K(`"${e}" restart "${s}"`,{cwd:a,stdio:"pipe"}),!await Q())throw new Error("Worker failed to become healthy after restart")}var z=new Set(["ListMcpResourcesTool"]);async function Z(a){if(!a)throw new Error("saveHook requires input");let{session_id:e,tool_name:s,tool_input:t,tool_output:r}=a;if(z.has(s)){console.log(f("PostToolUse",!0));return}await x();let n=new R,o=n.createSDKSession(e,"",""),i=n.getPromptCounter(o);n.close();let p=b.formatTool(s,t),u=L();b.dataIn("HOOK",`PostToolUse: ${p}`,{sessionId:o,workerPort:u});try{let c=await fetch(`http://127.0.0.1:${u}/sessions/${o}/observations`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({tool_name:s,tool_input:t!==void 0?JSON.stringify(t):"{}",tool_output:r!==void 0?JSON.stringify(r):"{}",prompt_number:i}),signal:AbortSignal.timeout(2e3)});if(!c.ok){let m=await c.text();throw b.failure("HOOK","Failed to send observation",{sessionId:o,status:c.status},m),new Error(`Failed to send observation to worker: ${c.status} ${m}`)}b.debug("HOOK","Observation sent successfully",{sessionId:o,toolName:s})}catch(c){throw c.cause?.code==="ECONNREFUSED"||c.name==="TimeoutError"||c.message.includes("fetch failed")?new Error("There's a problem with the worker. If you just updated, type `pm2 restart claude-mem-worker` in your terminal to continue"):c}console.log(f("PostToolUse",!0))}var A="";U.on("data",a=>A+=a);U.on("end",async()=>{let a=A?JSON.parse(A):void 0;await Z(a)});
|
||||
`;try{let T=this.db.prepare(c).all(p,u,...i),S=this.db.prepare(m).all(p,u,...i),_=this.db.prepare(g).all(p,u,...i);return{observations:T,sessions:S.map(d=>({id:d.id,sdk_session_id:d.sdk_session_id,project:d.project,request:d.request,completed:d.completed,next_steps:d.next_steps,created_at:d.created_at,created_at_epoch:d.created_at_epoch})),prompts:_.map(d=>({id:d.id,claude_session_id:d.claude_session_id,project:d.project,prompt:d.prompt_text,created_at:d.created_at,created_at_epoch:d.created_at_epoch}))}}catch(T){return console.error("[SessionStore] Error querying timeline records:",T.message),{observations:[],sessions:[],prompts:[]}}}close(){this.db.close()}};function $(a,e,s){return a==="PreCompact"?e?{continue:!0,suppressOutput:!0}:{continue:!1,stopReason:s.reason||"Pre-compact operation failed",suppressOutput:!0}:a==="SessionStart"?e&&s.context?{continue:!0,suppressOutput:!0,hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:s.context}}:{continue:!0,suppressOutput:!0}:a==="UserPromptSubmit"||a==="PostToolUse"?{continue:!0,suppressOutput:!0}:a==="Stop"?{continue:!0,suppressOutput:!0}:{continue:e,suppressOutput:!0,...s.reason&&!e?{stopReason:s.reason}:{}}}function f(a,e,s={}){let t=$(a,e,s);return JSON.stringify(t)}import I from"path";import{homedir as W}from"os";import{existsSync as G,readFileSync as Y}from"fs";import{execSync as K}from"child_process";var V=100,q=100,J=1e4;function L(){try{let a=I.join(W(),".claude-mem","settings.json");if(G(a)){let e=JSON.parse(Y(a,"utf-8")),s=parseInt(e.env?.CLAUDE_MEM_WORKER_PORT,10);if(!isNaN(s))return s}}catch{}return parseInt(process.env.CLAUDE_MEM_WORKER_PORT||"37777",10)}async function k(){try{let a=L();return(await fetch(`http://127.0.0.1:${a}/health`,{signal:AbortSignal.timeout(V)})).ok}catch{return!1}}async function Q(){let a=Date.now();for(;Date.now()-a<J;){if(await k())return!0;await new Promise(e=>setTimeout(e,q))}return!1}async function x(){if(await k())return;let a=D(),e=I.join(a,"node_modules",".bin","pm2"),s=I.join(a,"ecosystem.config.cjs");if(K(`"${e}" restart "${s}"`,{cwd:a,stdio:"pipe"}),!await Q())throw new Error("Worker failed to become healthy after restart")}var z=new Set(["ListMcpResourcesTool"]);async function Z(a){if(!a)throw new Error("saveHook requires input");let{session_id:e,tool_name:s,tool_input:t,tool_response:r}=a;if(z.has(s)){console.log(f("PostToolUse",!0));return}await x();let n=new R,o=n.createSDKSession(e,"",""),i=n.getPromptCounter(o);n.close();let p=b.formatTool(s,t),u=L();b.dataIn("HOOK",`PostToolUse: ${p}`,{sessionId:o,workerPort:u});try{let c=await fetch(`http://127.0.0.1:${u}/sessions/${o}/observations`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({tool_name:s,tool_input:t!==void 0?JSON.stringify(t):"{}",tool_response:r!==void 0?JSON.stringify(r):"{}",prompt_number:i}),signal:AbortSignal.timeout(2e3)});if(!c.ok){let m=await c.text();throw b.failure("HOOK","Failed to send observation",{sessionId:o,status:c.status},m),new Error(`Failed to send observation to worker: ${c.status} ${m}`)}b.debug("HOOK","Observation sent successfully",{sessionId:o,toolName:s})}catch(c){throw c.cause?.code==="ECONNREFUSED"||c.name==="TimeoutError"||c.message.includes("fetch failed")?new Error("There's a problem with the worker. If you just updated, type `pm2 restart claude-mem-worker` in your terminal to continue"):c}console.log(f("PostToolUse",!0))}var A="";U.on("data",a=>A+=a);U.on("end",async()=>{let a=A?JSON.parse(A):void 0;await Z(a)});
|
||||
|
||||
@@ -649,8 +649,8 @@ IMPORTANT: This is not the end of the session. You will receive more requests to
|
||||
WHERE up.claude_session_id = ?
|
||||
ORDER BY up.created_at_epoch DESC
|
||||
LIMIT 1
|
||||
`).get(n);o.close(),l&&this.broadcastSSE({type:"new_prompt",prompt:{id:l.id,claude_session_id:l.claude_session_id,project:l.project,prompt_number:l.prompt_number,prompt_text:l.prompt_text,created_at_epoch:l.created_at_epoch}}),l&&this.chromaSync.syncUserPrompt(l.id,l.sdk_session_id,l.project,l.prompt_text,l.prompt_number,l.created_at_epoch).catch(c=>{Y.failure("WORKER","Failed to sync user_prompt to Chroma - continuing",{promptId:l.id},c)}),this.broadcastProcessingStatus(!0),Y.success("WORKER","Session initialized",{sessionId:r,port:Cn()}),a.json({status:"initialized",sessionDbId:r,port:Cn()})}handleObservation(e,a){let r=parseInt(e.params.sessionDbId,10),{tool_name:s,tool_input:i,tool_output:n,prompt_number:o}=e.body,l=this.getOrCreateSession(r),c=Y.formatTool(s,i);Y.dataIn("WORKER",`Observation queued: ${c}`,{sessionId:r,queue:l.pendingMessages.length+1}),l.pendingMessages.push({type:"observation",tool_name:s,tool_input:i,tool_output:n,prompt_number:o}),a.json({status:"queued",queueLength:l.pendingMessages.length})}handleSummarize(e,a){let r=parseInt(e.params.sessionDbId,10),{prompt_number:s}=e.body,i=this.getOrCreateSession(r);Y.dataIn("WORKER","Summary requested",{sessionId:r,promptNumber:s,queue:i.pendingMessages.length+1}),i.pendingMessages.push({type:"summarize",prompt_number:s}),a.json({status:"queued",queueLength:i.pendingMessages.length})}handleComplete(e,a){let r=parseInt(e.params.sessionDbId,10);Y.info("WORKER","Session completed - stopping spinner",{sessionId:r}),this.broadcastProcessingStatus(!1),a.json({status:"ok"})}handleStatus(e,a){let r=parseInt(e.params.sessionDbId,10),s=this.sessions.get(r);if(!s){a.status(404).json({error:"Session not found"});return}a.json({sessionDbId:r,sdkSessionId:s.sdkSessionId,project:s.project,pendingMessages:s.pendingMessages.length})}async runSDKAgent(e){Y.info("SDK","Agent starting",{sessionId:e.sessionDbId});let a=a$();Y.info("SDK",`Using Claude executable: ${a}`,{sessionId:e.sessionDbId});try{let r=qb({prompt:this.createMessageGenerator(e),options:{model:Y5,disallowedTools:e$,abortController:e.abortController,pathToClaudeCodeExecutable:a}});for await(let n of r){if(n.type==="assistant"){let o=n.message.content,l=Array.isArray(o)?o.filter(u=>u.type==="text").map(u=>u.text).join(`
|
||||
`):typeof o=="string"?o:"",c=l.length;Y.dataOut("SDK",`Response received (${c} chars)`,{sessionId:e.sessionDbId,promptNumber:e.lastPromptNumber}),Y.debug("SDK","Full response",{sessionId:e.sessionDbId},l),this.handleAgentMessage(e,l,e.lastPromptNumber)}n.type==="result"&&n.subtype}let s=Date.now()-e.startTime;Y.success("SDK","Agent completed",{sessionId:e.sessionDbId,duration:`${(s/1e3).toFixed(1)}s`});let i=new br;i.markSessionCompleted(e.sessionDbId),i.close(),this.sessions.delete(e.sessionDbId)}catch(r){throw r.name==="AbortError"?Y.warn("SDK","Agent aborted",{sessionId:e.sessionDbId}):Y.failure("SDK","Agent error",{sessionId:e.sessionDbId},r),r}}async*createMessageGenerator(e){let a=fE(e.project,e.claudeSessionId,e.userPrompt);for(Y.dataIn("SDK",`Init prompt sent (${a.length} chars)`,{sessionId:e.sessionDbId,claudeSessionId:e.claudeSessionId,project:e.project}),Y.debug("SDK","Full init prompt",{sessionId:e.sessionDbId},a),yield{type:"user",session_id:e.claudeSessionId,parent_tool_use_id:null,message:{role:"user",content:a}};!e.abortController.signal.aborted;){if(e.pendingMessages.length===0){await new Promise(r=>setTimeout(r,r$));continue}for(;e.pendingMessages.length>0;){let r=e.pendingMessages.shift();if(r.type==="summarize"){e.lastPromptNumber=r.prompt_number;let s=new br,i=s.getSessionById(e.sessionDbId);s.close();let n=hE(i);Y.dataIn("SDK",`Summary prompt sent (${n.length} chars)`,{sessionId:e.sessionDbId,promptNumber:r.prompt_number}),Y.debug("SDK","Full summary prompt",{sessionId:e.sessionDbId},n),yield{type:"user",session_id:e.claudeSessionId,parent_tool_use_id:null,message:{role:"user",content:n}}}else if(r.type==="observation"){e.lastPromptNumber=r.prompt_number;let s=mE({id:0,tool_name:r.tool_name,tool_input:r.tool_input,tool_output:r.tool_output,created_at_epoch:Date.now()}),i=Y.formatTool(r.tool_name,r.tool_input);Y.dataIn("SDK",`Observation prompt: ${i}`,{sessionId:e.sessionDbId,promptNumber:r.prompt_number,size:`${s.length} chars`}),Y.debug("SDK","Full observation prompt",{sessionId:e.sessionDbId},s),yield{type:"user",session_id:e.claudeSessionId,parent_tool_use_id:null,message:{role:"user",content:s}}}}}}handleAgentMessage(e,a,r){Y.info("PARSER",`Processing response (${a.length} chars)`,{sessionId:e.sessionDbId,promptNumber:r,preview:a.substring(0,200)});let s=vE(a);s.length>0&&Y.info("PARSER",`Parsed ${s.length} observation(s)`,{sessionId:e.sessionDbId,promptNumber:r,types:s.map(o=>o.type).join(", ")});let i=new br;for(let o of s){let{id:l,createdAtEpoch:c}=i.storeObservation(e.claudeSessionId,e.project,o,r);Y.success("DB","Observation stored",{sessionId:e.sessionDbId,type:o.type,title:o.title,id:l}),this.broadcastSSE({type:"new_observation",observation:{id:l,session_id:e.claudeSessionId,type:o.type,title:o.title,subtitle:o.subtitle,project:e.project,prompt_number:r,created_at_epoch:c}}),this.chromaSync.syncObservation(l,e.claudeSessionId,e.project,o,r,c).then(()=>{Y.success("WORKER","Observation synced to Chroma",{sessionId:e.sessionDbId,observationId:l})}).catch(u=>{Y.error("WORKER","Observation sync failed - continuing",{sessionId:e.sessionDbId,observationId:l},u)})}Y.info("PARSER","Looking for summary tags...",{sessionId:e.sessionDbId});let n=gE(a,e.sessionDbId);if(n){Y.success("PARSER","Summary parsed successfully!",{sessionId:e.sessionDbId,promptNumber:r,hasRequest:!!n.request,hasInvestigated:!!n.investigated,hasLearned:!!n.learned,hasCompleted:!!n.completed,hasNextSteps:!!n.next_steps});let{id:o,createdAtEpoch:l}=i.storeSummary(e.claudeSessionId,e.project,n,r);Y.success("DB","\u{1F4DD} SUMMARY STORED IN DATABASE",{sessionId:e.sessionDbId,promptNumber:r,id:o}),this.broadcastSSE({type:"new_summary",summary:{id:o,session_id:e.claudeSessionId,request:n.request,investigated:n.investigated,learned:n.learned,completed:n.completed,next_steps:n.next_steps,notes:n.notes,project:e.project,prompt_number:r,created_at_epoch:l}}),this.chromaSync.syncSummary(o,e.claudeSessionId,e.project,n,r,l).then(()=>{Y.success("WORKER","Summary synced to Chroma",{sessionId:e.sessionDbId,summaryId:o})}).catch(c=>{Y.error("WORKER","Summary sync failed - continuing",{sessionId:e.sessionDbId,summaryId:o},c)})}else Y.warn("PARSER","NO SUMMARY TAGS FOUND in response",{sessionId:e.sessionDbId,promptNumber:r,contentSample:a.substring(0,500)});i.close(),this.checkAndStopSpinner()}};async function s$(){await new Qc().start(),process.on("SIGINT",()=>{Y.warn("SYSTEM","Shutting down (SIGINT)"),process.exit(0)}),process.on("SIGTERM",()=>{Y.warn("SYSTEM","Shutting down (SIGTERM)"),process.exit(0)})}s$().catch(t=>{Y.failure("SYSTEM","Fatal startup error",{},t),process.exit(1)});0&&(module.exports={WorkerService});
|
||||
`).get(n);o.close(),l&&this.broadcastSSE({type:"new_prompt",prompt:{id:l.id,claude_session_id:l.claude_session_id,project:l.project,prompt_number:l.prompt_number,prompt_text:l.prompt_text,created_at_epoch:l.created_at_epoch}}),l&&this.chromaSync.syncUserPrompt(l.id,l.sdk_session_id,l.project,l.prompt_text,l.prompt_number,l.created_at_epoch).catch(c=>{Y.failure("WORKER","Failed to sync user_prompt to Chroma - continuing",{promptId:l.id},c)}),this.broadcastProcessingStatus(!0),Y.success("WORKER","Session initialized",{sessionId:r,port:Cn()}),a.json({status:"initialized",sessionDbId:r,port:Cn()})}handleObservation(e,a){let r=parseInt(e.params.sessionDbId,10),{tool_name:s,tool_input:i,tool_response:n,prompt_number:o}=e.body,l=this.getOrCreateSession(r),c=Y.formatTool(s,i);Y.dataIn("WORKER",`Observation queued: ${c}`,{sessionId:r,queue:l.pendingMessages.length+1}),l.pendingMessages.push({type:"observation",tool_name:s,tool_input:i,tool_response:n,prompt_number:o}),a.json({status:"queued",queueLength:l.pendingMessages.length})}handleSummarize(e,a){let r=parseInt(e.params.sessionDbId,10),{prompt_number:s}=e.body,i=this.getOrCreateSession(r);Y.dataIn("WORKER","Summary requested",{sessionId:r,promptNumber:s,queue:i.pendingMessages.length+1}),i.pendingMessages.push({type:"summarize",prompt_number:s}),a.json({status:"queued",queueLength:i.pendingMessages.length})}handleComplete(e,a){let r=parseInt(e.params.sessionDbId,10);Y.info("WORKER","Session completed - stopping spinner",{sessionId:r}),this.broadcastProcessingStatus(!1),a.json({status:"ok"})}handleStatus(e,a){let r=parseInt(e.params.sessionDbId,10),s=this.sessions.get(r);if(!s){a.status(404).json({error:"Session not found"});return}a.json({sessionDbId:r,sdkSessionId:s.sdkSessionId,project:s.project,pendingMessages:s.pendingMessages.length})}async runSDKAgent(e){Y.info("SDK","Agent starting",{sessionId:e.sessionDbId});let a=a$();Y.info("SDK",`Using Claude executable: ${a}`,{sessionId:e.sessionDbId});try{let r=qb({prompt:this.createMessageGenerator(e),options:{model:Y5,disallowedTools:e$,abortController:e.abortController,pathToClaudeCodeExecutable:a}});for await(let n of r){if(n.type==="assistant"){let o=n.message.content,l=Array.isArray(o)?o.filter(u=>u.type==="text").map(u=>u.text).join(`
|
||||
`):typeof o=="string"?o:"",c=l.length;Y.dataOut("SDK",`Response received (${c} chars)`,{sessionId:e.sessionDbId,promptNumber:e.lastPromptNumber}),Y.debug("SDK","Full response",{sessionId:e.sessionDbId},l),this.handleAgentMessage(e,l,e.lastPromptNumber)}n.type==="result"&&n.subtype}let s=Date.now()-e.startTime;Y.success("SDK","Agent completed",{sessionId:e.sessionDbId,duration:`${(s/1e3).toFixed(1)}s`});let i=new br;i.markSessionCompleted(e.sessionDbId),i.close(),this.sessions.delete(e.sessionDbId)}catch(r){throw r.name==="AbortError"?Y.warn("SDK","Agent aborted",{sessionId:e.sessionDbId}):Y.failure("SDK","Agent error",{sessionId:e.sessionDbId},r),r}}async*createMessageGenerator(e){let a=fE(e.project,e.claudeSessionId,e.userPrompt);for(Y.dataIn("SDK",`Init prompt sent (${a.length} chars)`,{sessionId:e.sessionDbId,claudeSessionId:e.claudeSessionId,project:e.project}),Y.debug("SDK","Full init prompt",{sessionId:e.sessionDbId},a),yield{type:"user",session_id:e.claudeSessionId,parent_tool_use_id:null,message:{role:"user",content:a}};!e.abortController.signal.aborted;){if(e.pendingMessages.length===0){await new Promise(r=>setTimeout(r,r$));continue}for(;e.pendingMessages.length>0;){let r=e.pendingMessages.shift();if(r.type==="summarize"){e.lastPromptNumber=r.prompt_number;let s=new br,i=s.getSessionById(e.sessionDbId);s.close();let n=hE(i);Y.dataIn("SDK",`Summary prompt sent (${n.length} chars)`,{sessionId:e.sessionDbId,promptNumber:r.prompt_number}),Y.debug("SDK","Full summary prompt",{sessionId:e.sessionDbId},n),yield{type:"user",session_id:e.claudeSessionId,parent_tool_use_id:null,message:{role:"user",content:n}}}else if(r.type==="observation"){e.lastPromptNumber=r.prompt_number;let s=mE({id:0,tool_name:r.tool_name,tool_input:r.tool_input,tool_output:r.tool_response,created_at_epoch:Date.now()}),i=Y.formatTool(r.tool_name,r.tool_input);Y.dataIn("SDK",`Observation prompt: ${i}`,{sessionId:e.sessionDbId,promptNumber:r.prompt_number,size:`${s.length} chars`}),Y.debug("SDK","Full observation prompt",{sessionId:e.sessionDbId},s),yield{type:"user",session_id:e.claudeSessionId,parent_tool_use_id:null,message:{role:"user",content:s}}}}}}handleAgentMessage(e,a,r){Y.info("PARSER",`Processing response (${a.length} chars)`,{sessionId:e.sessionDbId,promptNumber:r,preview:a.substring(0,200)});let s=vE(a);s.length>0&&Y.info("PARSER",`Parsed ${s.length} observation(s)`,{sessionId:e.sessionDbId,promptNumber:r,types:s.map(o=>o.type).join(", ")});let i=new br;for(let o of s){let{id:l,createdAtEpoch:c}=i.storeObservation(e.claudeSessionId,e.project,o,r);Y.success("DB","Observation stored",{sessionId:e.sessionDbId,type:o.type,title:o.title,id:l}),this.broadcastSSE({type:"new_observation",observation:{id:l,session_id:e.claudeSessionId,type:o.type,title:o.title,subtitle:o.subtitle,project:e.project,prompt_number:r,created_at_epoch:c}}),this.chromaSync.syncObservation(l,e.claudeSessionId,e.project,o,r,c).then(()=>{Y.success("WORKER","Observation synced to Chroma",{sessionId:e.sessionDbId,observationId:l})}).catch(u=>{Y.error("WORKER","Observation sync failed - continuing",{sessionId:e.sessionDbId,observationId:l},u)})}Y.info("PARSER","Looking for summary tags...",{sessionId:e.sessionDbId});let n=gE(a,e.sessionDbId);if(n){Y.success("PARSER","Summary parsed successfully!",{sessionId:e.sessionDbId,promptNumber:r,hasRequest:!!n.request,hasInvestigated:!!n.investigated,hasLearned:!!n.learned,hasCompleted:!!n.completed,hasNextSteps:!!n.next_steps});let{id:o,createdAtEpoch:l}=i.storeSummary(e.claudeSessionId,e.project,n,r);Y.success("DB","\u{1F4DD} SUMMARY STORED IN DATABASE",{sessionId:e.sessionDbId,promptNumber:r,id:o}),this.broadcastSSE({type:"new_summary",summary:{id:o,session_id:e.claudeSessionId,request:n.request,investigated:n.investigated,learned:n.learned,completed:n.completed,next_steps:n.next_steps,notes:n.notes,project:e.project,prompt_number:r,created_at_epoch:l}}),this.chromaSync.syncSummary(o,e.claudeSessionId,e.project,n,r,l).then(()=>{Y.success("WORKER","Summary synced to Chroma",{sessionId:e.sessionDbId,summaryId:o})}).catch(c=>{Y.error("WORKER","Summary sync failed - continuing",{sessionId:e.sessionDbId,summaryId:o},c)})}else Y.warn("PARSER","NO SUMMARY TAGS FOUND in response",{sessionId:e.sessionDbId,promptNumber:r,contentSample:a.substring(0,500)});i.close(),this.checkAndStopSpinner()}};async function s$(){await new Qc().start(),process.on("SIGINT",()=>{Y.warn("SYSTEM","Shutting down (SIGINT)"),process.exit(0)}),process.on("SIGTERM",()=>{Y.warn("SYSTEM","Shutting down (SIGTERM)"),process.exit(0)})}s$().catch(t=>{Y.failure("SYSTEM","Fatal startup error",{},t),process.exit(1)});0&&(module.exports={WorkerService});
|
||||
/*! Bundled license information:
|
||||
|
||||
depd/index.js:
|
||||
|
||||
@@ -14,7 +14,7 @@ export interface PostToolUseInput {
|
||||
cwd: string;
|
||||
tool_name: string;
|
||||
tool_input: any;
|
||||
tool_output: any;
|
||||
tool_response: any;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ async function saveHook(input?: PostToolUseInput): Promise<void> {
|
||||
throw new Error('saveHook requires input');
|
||||
}
|
||||
|
||||
const { session_id, tool_name, tool_input, tool_output } = input;
|
||||
const { session_id, tool_name, tool_input, tool_response } = input;
|
||||
|
||||
if (SKIP_TOOLS.has(tool_name)) {
|
||||
console.log(createHookResponse('PostToolUse', true));
|
||||
@@ -64,7 +64,7 @@ async function saveHook(input?: PostToolUseInput): Promise<void> {
|
||||
body: JSON.stringify({
|
||||
tool_name,
|
||||
tool_input: tool_input !== undefined ? JSON.stringify(tool_input) : '{}',
|
||||
tool_output: tool_output !== undefined ? JSON.stringify(tool_output) : '{}',
|
||||
tool_response: tool_response !== undefined ? JSON.stringify(tool_response) : '{}',
|
||||
prompt_number: promptNumber
|
||||
}),
|
||||
signal: AbortSignal.timeout(2000)
|
||||
|
||||
@@ -206,12 +206,12 @@ export class WorkerService {
|
||||
private handleObservations(req: Request, res: Response): void {
|
||||
try {
|
||||
const sessionDbId = parseInt(req.params.sessionDbId, 10);
|
||||
const { tool_name, tool_input, tool_output, prompt_number } = req.body;
|
||||
const { tool_name, tool_input, tool_response, prompt_number } = req.body;
|
||||
|
||||
this.sessionManager.queueObservation(sessionDbId, {
|
||||
tool_name,
|
||||
tool_input,
|
||||
tool_output,
|
||||
tool_response,
|
||||
prompt_number
|
||||
});
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ interface ObservationMessage {
|
||||
type: 'observation';
|
||||
tool_name: string;
|
||||
tool_input: string;
|
||||
tool_output: string;
|
||||
tool_response: string;
|
||||
prompt_number: number;
|
||||
}
|
||||
|
||||
@@ -753,11 +753,11 @@ class WorkerService {
|
||||
|
||||
/**
|
||||
* POST /sessions/:sessionDbId/observations
|
||||
* Body: { tool_name, tool_input, tool_output, prompt_number }
|
||||
* Body: { tool_name, tool_input, tool_response, prompt_number }
|
||||
*/
|
||||
private handleObservation(req: Request, res: Response): void {
|
||||
const sessionDbId = parseInt(req.params.sessionDbId, 10);
|
||||
const { tool_name, tool_input, tool_output, prompt_number } = req.body;
|
||||
const { tool_name, tool_input, tool_response, prompt_number } = req.body;
|
||||
|
||||
const session = this.getOrCreateSession(sessionDbId);
|
||||
const toolStr = logger.formatTool(tool_name, tool_input);
|
||||
@@ -771,7 +771,7 @@ class WorkerService {
|
||||
type: 'observation',
|
||||
tool_name,
|
||||
tool_input,
|
||||
tool_output,
|
||||
tool_response,
|
||||
prompt_number
|
||||
});
|
||||
|
||||
@@ -977,7 +977,7 @@ class WorkerService {
|
||||
id: 0,
|
||||
tool_name: message.tool_name,
|
||||
tool_input: message.tool_input,
|
||||
tool_output: message.tool_output,
|
||||
tool_output: message.tool_response,
|
||||
created_at_epoch: Date.now()
|
||||
});
|
||||
|
||||
|
||||
@@ -25,14 +25,14 @@ export interface PendingMessage {
|
||||
type: 'observation' | 'summarize';
|
||||
tool_name?: string;
|
||||
tool_input?: any;
|
||||
tool_output?: any;
|
||||
tool_response?: any;
|
||||
prompt_number?: number;
|
||||
}
|
||||
|
||||
export interface ObservationData {
|
||||
tool_name: string;
|
||||
tool_input: any;
|
||||
tool_output: any;
|
||||
tool_response: any;
|
||||
prompt_number: number;
|
||||
}
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ export class SDKAgent {
|
||||
id: 0, // Not used in prompt
|
||||
tool_name: message.tool_name!,
|
||||
tool_input: JSON.stringify(message.tool_input),
|
||||
tool_output: JSON.stringify(message.tool_output),
|
||||
tool_output: JSON.stringify(message.tool_response),
|
||||
created_at_epoch: Date.now()
|
||||
})
|
||||
},
|
||||
|
||||
@@ -80,7 +80,7 @@ export class SessionManager {
|
||||
type: 'observation',
|
||||
tool_name: data.tool_name,
|
||||
tool_input: data.tool_input,
|
||||
tool_output: data.tool_output,
|
||||
tool_response: data.tool_response,
|
||||
prompt_number: data.prompt_number
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user