From d7b9f68d80e7407f65ddb43fa63b3b3cf2096f16 Mon Sep 17 00:00:00 2001 From: Alex Newman Date: Fri, 24 Oct 2025 20:50:31 -0400 Subject: [PATCH] Release v4.2.4: Enhanced summary prompt clarity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improvements: - Removed optional skip_summary functionality (summaries now always generated) - Clarified that summaries are mid-session checkpoints, not session endings - Improved request field instructions to better form descriptive titles - Changed wording from "discovered" to "learned" for consistency Technical changes: - Updated src/sdk/prompts.ts summary prompt - Removed "WHEN NOT TO SUMMARIZE" section - Added clarifying footer text about ongoing sessions - Updated built worker-service.cjs - Bumped version to 4.2.4 in all metadata files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .claude-plugin/marketplace.json | 2 +- CLAUDE.md | 20 ++++++++++++++++++-- package.json | 2 +- plugin/.claude-plugin/plugin.json | 2 +- plugin/scripts/worker-service.cjs | 15 ++++++--------- src/sdk/prompts.ts | 15 ++++++--------- 6 files changed, 33 insertions(+), 23 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 6f1e66a0..c011487a 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -10,7 +10,7 @@ "plugins": [ { "name": "claude-mem", - "version": "4.2.3", + "version": "4.2.4", "source": "./plugin", "description": "Persistent memory system for Claude Code - context compression across sessions" } diff --git a/CLAUDE.md b/CLAUDE.md index c7bf2d4f..6a491826 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ Claude-mem is a persistent memory compression system that preserves context across Claude Code sessions. It automatically captures tool usage observations, processes them through the Claude Agent SDK, and makes summaries available to future sessions. -**Current Version**: 4.2.3 +**Current Version**: 4.2.4 **License**: AGPL-3.0 **Author**: Alex Newman (@thedotmack) @@ -210,7 +210,23 @@ npm run build && git commit -a -m "Build and update" && git push && cd ~/.claude ## Version History -### v4.2.3 (Current) +### v4.2.4 (Current) +**Breaking Changes**: None (patch version) + +**Improvements**: +- Enhanced summary prompt clarity and reliability + - Removed optional skip_summary functionality (summaries now always generated) + - Clarified that summaries are mid-session checkpoints, not session endings + - Improved request field instructions to better form descriptive titles + - Changed wording from "discovered" to "learned" for consistency + +**Technical Details**: +- Updated `src/sdk/prompts.ts` to remove `WHEN NOT TO SUMMARIZE` section +- Added footer text clarifying summaries track progress within ongoing sessions +- Changed request field prompt from "Use their original sentiment" to "Form a title that reflects the actual request" +- Affects both observation and summary prompt generation + +### v4.2.3 **Breaking Changes**: None (patch version) **Security**: diff --git a/package.json b/package.json index eb460fa2..dc33b696 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "claude-mem", - "version": "4.2.3", + "version": "4.2.4", "description": "Memory compression system for Claude Code - persist context across sessions", "keywords": [ "claude", diff --git a/plugin/.claude-plugin/plugin.json b/plugin/.claude-plugin/plugin.json index d4be2995..abc1e120 100644 --- a/plugin/.claude-plugin/plugin.json +++ b/plugin/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "claude-mem", - "version": "4.2.3", + "version": "4.2.4", "description": "Persistent memory system for Claude Code - seamlessly preserve context across sessions", "author": { "name": "Alex Newman" diff --git a/plugin/scripts/worker-service.cjs b/plugin/scripts/worker-service.cjs index e6e64984..7ba499d6 100755 --- a/plugin/scripts/worker-service.cjs +++ b/plugin/scripts/worker-service.cjs @@ -477,12 +477,6 @@ IMPORTANT! DO NOT summarize the observation process itself - you are summarizing User's Original Request: ${a.user_prompt} -WHEN NOT TO SUMMARIZE ----------------------- -Do not summarize if the request is conversational and unrelated to the work that was just completed. - -If skipping, **output only**: - \u2705 GOOD - Describes deliverables: Fix authentication timeout bug Add three-tier verbosity system to session summaries @@ -495,16 +489,19 @@ If skipping, **output only**: Output this XML: - [What did the user request? Use their original sentiment from: ${a.user_prompt}] + [What did the user request? Form a title that reflects the actual request: ${a.user_prompt}] [What was explored?] - [What was discovered about how things work?] + [What was learned about how things work?] [What shipped? What does the system now do?] [What are the next steps?] [Additional insights] **Required fields**: request, investigated, learned, completed, next_steps -**Optional fields**: notes`}function xg(a,e){let r=[],t=/([\s\S]*?)<\/observation>/g,i;for(;(i=t.exec(a))!==null;){let s=i[1],n=Vt(s,"type"),o=Vt(s,"title"),p=Vt(s,"subtitle"),c=Vt(s,"narrative"),l=ps(s,"facts","fact"),u=ps(s,"concepts","concept"),d=ps(s,"files_read","file"),m=ps(s,"files_modified","file");if(!n||!o||!p||!c){ie.warn("PARSER","Observation missing required fields, skipping",{correlationId:e,hasType:!!n,hasTitle:!!o,hasSubtitle:!!p,hasNarrative:!!c});continue}if(!["bugfix","feature","refactor","change","discovery","decision"].includes(n.trim())){ie.warn("PARSER",`Invalid observation type: ${n}, skipping`,{correlationId:e});continue}let f=u.filter(g=>g!==n.trim());f.length!==u.length&&ie.warn("PARSER","Removed observation type from concepts array",{correlationId:e,type:n.trim(),originalConcepts:u,cleanedConcepts:f}),r.push({type:n.trim(),title:o,subtitle:p,facts:l,narrative:c,concepts:f,files_read:d,files_modified:m})}return r}function yg(a,e){let t=//.exec(a);if(t)return ie.info("PARSER","Summary skipped",{sessionId:e,reason:t[1]}),null;let s=/([\s\S]*?)<\/summary>/.exec(a);if(!s)return null;let n=s[1],o=Vt(n,"request"),p=Vt(n,"investigated"),c=Vt(n,"learned"),l=Vt(n,"completed"),u=Vt(n,"next_steps"),d=Vt(n,"notes");return!o||!p||!c||!l||!u?(ie.warn("PARSER","Summary missing required fields",{sessionId:e,hasRequest:!!o,hasInvestigated:!!p,hasLearned:!!c,hasCompleted:!!l,hasNextSteps:!!u}),null):{request:o,investigated:p,learned:c,completed:l,next_steps:u,notes:d}}function Vt(a,e){let t=new RegExp(`<${e}>([^<]*)`).exec(a);return t?t[1].trim():null}function ps(a,e,r){let t=[],s=new RegExp(`<${e}>(.*?)`,"s").exec(a);if(!s)return t;let n=s[1],o=new RegExp(`<${r}>([^<]+)`,"g"),p;for(;(p=o.exec(n))!==null;)t.push(p[1].trim());return t}var Q2=process.env.CLAUDE_MEM_MODEL||"claude-sonnet-4-5",J2=["Glob","Grep","ListMcpResourcesTool","WebSearch"],ls=parseInt(process.env.CLAUDE_MEM_WORKER_PORT||"37777",10),us=class{app;port=null;sessions=new Map;constructor(){this.app=(0,Vc.default)(),this.app.use(Vc.default.json({limit:"50mb"})),this.app.get("/health",this.handleHealth.bind(this)),this.app.post("/sessions/:sessionDbId/init",this.handleInit.bind(this)),this.app.post("/sessions/:sessionDbId/observations",this.handleObservation.bind(this)),this.app.post("/sessions/:sessionDbId/summarize",this.handleSummarize.bind(this)),this.app.get("/sessions/:sessionDbId/status",this.handleStatus.bind(this)),this.app.delete("/sessions/:sessionDbId",this.handleDelete.bind(this))}async start(){this.port=ls;let e=new nt,r=e.cleanupOrphanedSessions();return e.close(),r>0&&ie.info("SYSTEM",`Cleaned up ${r} orphaned sessions`),new Promise((t,i)=>{this.app.listen(ls,"127.0.0.1",()=>{ie.info("SYSTEM","Worker started",{port:ls,pid:process.pid,activeSessions:this.sessions.size}),t()}).on("error",s=>{s.code==="EADDRINUSE"&&ie.error("SYSTEM",`Port ${ls} already in use - worker may already be running`),i(s)})})}handleHealth(e,r){r.json({status:"ok",port:this.port,pid:process.pid,activeSessions:this.sessions.size,uptime:process.uptime(),memory:process.memoryUsage()})}async handleInit(e,r){let t=parseInt(e.params.sessionDbId,10),{project:i,userPrompt:s}=e.body,n=ie.sessionId(t);ie.info("WORKER","Session init",{correlationId:n,project:i});let o=new nt,p=o.getSessionById(t);if(!p){o.close(),r.status(404).json({error:"Session not found in database"});return}let c=p.sdk_session_id||`session-${t}`,l={sessionDbId:t,claudeSessionId:c,sdkSessionId:p.sdk_session_id||null,project:i,userPrompt:s,pendingMessages:[],abortController:new AbortController,generatorPromise:null,lastPromptNumber:0,observationCounter:0,startTime:Date.now()};this.sessions.set(t,l),o.setWorkerPort(t,this.port),o.close(),l.generatorPromise=this.runSDKAgent(l).catch(u=>{ie.failure("WORKER","SDK agent error",{sessionId:t},u);let d=new nt;d.markSessionFailed(t),d.close(),this.sessions.delete(t)}),ie.success("WORKER","Session initialized",{sessionId:t,port:this.port}),r.json({status:"initialized",sessionDbId:t,port:this.port})}handleObservation(e,r){let t=parseInt(e.params.sessionDbId,10),{tool_name:i,tool_input:s,tool_output:n,prompt_number:o}=e.body,p=this.sessions.get(t);if(!p){let u=new nt,d=u.getSessionById(t);u.close();let m=d?.sdk_session_id||`session-${t}`;p={sessionDbId:t,claudeSessionId:m,sdkSessionId:null,project:d?.project||"",userPrompt:d?.user_prompt||"",pendingMessages:[],abortController:new AbortController,generatorPromise:null,lastPromptNumber:0,observationCounter:0,startTime:Date.now()},this.sessions.set(t,p),p.generatorPromise=this.runSDKAgent(p).catch(v=>{ie.failure("WORKER","SDK agent error",{sessionId:t},v);let f=new nt;f.markSessionFailed(t),f.close(),this.sessions.delete(t)})}p.observationCounter++;let c=ie.correlationId(t,p.observationCounter),l=ie.formatTool(i,s);ie.dataIn("WORKER",`Observation queued: ${l}`,{correlationId:c,queue:p.pendingMessages.length+1}),p.pendingMessages.push({type:"observation",tool_name:i,tool_input:s,tool_output:n,prompt_number:o}),r.json({status:"queued",queueLength:p.pendingMessages.length})}handleSummarize(e,r){let t=parseInt(e.params.sessionDbId,10),{prompt_number:i}=e.body,s=this.sessions.get(t);if(!s){let n=new nt,o=n.getSessionById(t);n.close();let p=o?.sdk_session_id||`session-${t}`;s={sessionDbId:t,claudeSessionId:p,sdkSessionId:null,project:o?.project||"",userPrompt:o?.user_prompt||"",pendingMessages:[],abortController:new AbortController,generatorPromise:null,lastPromptNumber:0,observationCounter:0,startTime:Date.now()},this.sessions.set(t,s),s.generatorPromise=this.runSDKAgent(s).catch(c=>{ie.failure("WORKER","SDK agent error",{sessionId:t},c);let l=new nt;l.markSessionFailed(t),l.close(),this.sessions.delete(t)})}ie.dataIn("WORKER","Summary requested",{sessionId:t,promptNumber:i,queue:s.pendingMessages.length+1}),s.pendingMessages.push({type:"summarize",prompt_number:i}),r.json({status:"queued",queueLength:s.pendingMessages.length})}handleStatus(e,r){let t=parseInt(e.params.sessionDbId,10),i=this.sessions.get(t);if(!i){r.status(404).json({error:"Session not found"});return}r.json({sessionDbId:t,sdkSessionId:i.sdkSessionId,project:i.project,pendingMessages:i.pendingMessages.length})}async handleDelete(e,r){let t=parseInt(e.params.sessionDbId,10),i=this.sessions.get(t);if(!i){r.status(404).json({error:"Session not found"});return}ie.warn("WORKER","Session delete requested",{sessionId:t}),i.abortController.abort(),i.generatorPromise&&await Promise.race([i.generatorPromise,new Promise(n=>setTimeout(n,5e3))]);let s=new nt;s.markSessionFailed(t),s.close(),this.sessions.delete(t),ie.info("WORKER","Session deleted",{sessionId:t}),r.json({status:"deleted"})}async runSDKAgent(e){ie.info("SDK","Agent starting",{sessionId:e.sessionDbId});let r=process.env.CLAUDE_CODE_PATH||"/Users/alexnewman/.nvm/versions/node/v24.5.0/bin/claude";try{let t=lg({prompt:this.createMessageGenerator(e),options:{model:Q2,disallowedTools:J2,abortController:e.abortController,pathToClaudeCodeExecutable:r}});for await(let n of t)if(n.type==="system"&&n.subtype==="init"){let o=n;if(o.session_id){let p=new nt,c=p.updateSDKSessionId(e.sessionDbId,o.session_id);p.close(),c&&(ie.success("SDK","Session initialized",{sessionId:e.sessionDbId,sdkSessionId:o.session_id}),e.sdkSessionId=o.session_id)}}else if(n.type==="assistant"){let o=n.message.content,p=Array.isArray(o)?o.filter(l=>l.type==="text").map(l=>l.text).join(` +**Optional fields**: notes + +IMPORTANT: This is not the end of the session. You will receive more requests to process, and more tool usages to observe and record. The summary helps keep track of progress. +`}function xg(a,e){let r=[],t=/([\s\S]*?)<\/observation>/g,i;for(;(i=t.exec(a))!==null;){let s=i[1],n=Vt(s,"type"),o=Vt(s,"title"),p=Vt(s,"subtitle"),c=Vt(s,"narrative"),l=ps(s,"facts","fact"),u=ps(s,"concepts","concept"),d=ps(s,"files_read","file"),m=ps(s,"files_modified","file");if(!n||!o||!p||!c){ie.warn("PARSER","Observation missing required fields, skipping",{correlationId:e,hasType:!!n,hasTitle:!!o,hasSubtitle:!!p,hasNarrative:!!c});continue}if(!["bugfix","feature","refactor","change","discovery","decision"].includes(n.trim())){ie.warn("PARSER",`Invalid observation type: ${n}, skipping`,{correlationId:e});continue}let f=u.filter(g=>g!==n.trim());f.length!==u.length&&ie.warn("PARSER","Removed observation type from concepts array",{correlationId:e,type:n.trim(),originalConcepts:u,cleanedConcepts:f}),r.push({type:n.trim(),title:o,subtitle:p,facts:l,narrative:c,concepts:f,files_read:d,files_modified:m})}return r}function yg(a,e){let t=//.exec(a);if(t)return ie.info("PARSER","Summary skipped",{sessionId:e,reason:t[1]}),null;let s=/([\s\S]*?)<\/summary>/.exec(a);if(!s)return null;let n=s[1],o=Vt(n,"request"),p=Vt(n,"investigated"),c=Vt(n,"learned"),l=Vt(n,"completed"),u=Vt(n,"next_steps"),d=Vt(n,"notes");return!o||!p||!c||!l||!u?(ie.warn("PARSER","Summary missing required fields",{sessionId:e,hasRequest:!!o,hasInvestigated:!!p,hasLearned:!!c,hasCompleted:!!l,hasNextSteps:!!u}),null):{request:o,investigated:p,learned:c,completed:l,next_steps:u,notes:d}}function Vt(a,e){let t=new RegExp(`<${e}>([^<]*)`).exec(a);return t?t[1].trim():null}function ps(a,e,r){let t=[],s=new RegExp(`<${e}>(.*?)`,"s").exec(a);if(!s)return t;let n=s[1],o=new RegExp(`<${r}>([^<]+)`,"g"),p;for(;(p=o.exec(n))!==null;)t.push(p[1].trim());return t}var Q2=process.env.CLAUDE_MEM_MODEL||"claude-sonnet-4-5",J2=["Glob","Grep","ListMcpResourcesTool","WebSearch"],ls=parseInt(process.env.CLAUDE_MEM_WORKER_PORT||"37777",10),us=class{app;port=null;sessions=new Map;constructor(){this.app=(0,Vc.default)(),this.app.use(Vc.default.json({limit:"50mb"})),this.app.get("/health",this.handleHealth.bind(this)),this.app.post("/sessions/:sessionDbId/init",this.handleInit.bind(this)),this.app.post("/sessions/:sessionDbId/observations",this.handleObservation.bind(this)),this.app.post("/sessions/:sessionDbId/summarize",this.handleSummarize.bind(this)),this.app.get("/sessions/:sessionDbId/status",this.handleStatus.bind(this)),this.app.delete("/sessions/:sessionDbId",this.handleDelete.bind(this))}async start(){this.port=ls;let e=new nt,r=e.cleanupOrphanedSessions();return e.close(),r>0&&ie.info("SYSTEM",`Cleaned up ${r} orphaned sessions`),new Promise((t,i)=>{this.app.listen(ls,"127.0.0.1",()=>{ie.info("SYSTEM","Worker started",{port:ls,pid:process.pid,activeSessions:this.sessions.size}),t()}).on("error",s=>{s.code==="EADDRINUSE"&&ie.error("SYSTEM",`Port ${ls} already in use - worker may already be running`),i(s)})})}handleHealth(e,r){r.json({status:"ok",port:this.port,pid:process.pid,activeSessions:this.sessions.size,uptime:process.uptime(),memory:process.memoryUsage()})}async handleInit(e,r){let t=parseInt(e.params.sessionDbId,10),{project:i,userPrompt:s}=e.body,n=ie.sessionId(t);ie.info("WORKER","Session init",{correlationId:n,project:i});let o=new nt,p=o.getSessionById(t);if(!p){o.close(),r.status(404).json({error:"Session not found in database"});return}let c=p.sdk_session_id||`session-${t}`,l={sessionDbId:t,claudeSessionId:c,sdkSessionId:p.sdk_session_id||null,project:i,userPrompt:s,pendingMessages:[],abortController:new AbortController,generatorPromise:null,lastPromptNumber:0,observationCounter:0,startTime:Date.now()};this.sessions.set(t,l),o.setWorkerPort(t,this.port),o.close(),l.generatorPromise=this.runSDKAgent(l).catch(u=>{ie.failure("WORKER","SDK agent error",{sessionId:t},u);let d=new nt;d.markSessionFailed(t),d.close(),this.sessions.delete(t)}),ie.success("WORKER","Session initialized",{sessionId:t,port:this.port}),r.json({status:"initialized",sessionDbId:t,port:this.port})}handleObservation(e,r){let t=parseInt(e.params.sessionDbId,10),{tool_name:i,tool_input:s,tool_output:n,prompt_number:o}=e.body,p=this.sessions.get(t);if(!p){let u=new nt,d=u.getSessionById(t);u.close();let m=d?.sdk_session_id||`session-${t}`;p={sessionDbId:t,claudeSessionId:m,sdkSessionId:null,project:d?.project||"",userPrompt:d?.user_prompt||"",pendingMessages:[],abortController:new AbortController,generatorPromise:null,lastPromptNumber:0,observationCounter:0,startTime:Date.now()},this.sessions.set(t,p),p.generatorPromise=this.runSDKAgent(p).catch(v=>{ie.failure("WORKER","SDK agent error",{sessionId:t},v);let f=new nt;f.markSessionFailed(t),f.close(),this.sessions.delete(t)})}p.observationCounter++;let c=ie.correlationId(t,p.observationCounter),l=ie.formatTool(i,s);ie.dataIn("WORKER",`Observation queued: ${l}`,{correlationId:c,queue:p.pendingMessages.length+1}),p.pendingMessages.push({type:"observation",tool_name:i,tool_input:s,tool_output:n,prompt_number:o}),r.json({status:"queued",queueLength:p.pendingMessages.length})}handleSummarize(e,r){let t=parseInt(e.params.sessionDbId,10),{prompt_number:i}=e.body,s=this.sessions.get(t);if(!s){let n=new nt,o=n.getSessionById(t);n.close();let p=o?.sdk_session_id||`session-${t}`;s={sessionDbId:t,claudeSessionId:p,sdkSessionId:null,project:o?.project||"",userPrompt:o?.user_prompt||"",pendingMessages:[],abortController:new AbortController,generatorPromise:null,lastPromptNumber:0,observationCounter:0,startTime:Date.now()},this.sessions.set(t,s),s.generatorPromise=this.runSDKAgent(s).catch(c=>{ie.failure("WORKER","SDK agent error",{sessionId:t},c);let l=new nt;l.markSessionFailed(t),l.close(),this.sessions.delete(t)})}ie.dataIn("WORKER","Summary requested",{sessionId:t,promptNumber:i,queue:s.pendingMessages.length+1}),s.pendingMessages.push({type:"summarize",prompt_number:i}),r.json({status:"queued",queueLength:s.pendingMessages.length})}handleStatus(e,r){let t=parseInt(e.params.sessionDbId,10),i=this.sessions.get(t);if(!i){r.status(404).json({error:"Session not found"});return}r.json({sessionDbId:t,sdkSessionId:i.sdkSessionId,project:i.project,pendingMessages:i.pendingMessages.length})}async handleDelete(e,r){let t=parseInt(e.params.sessionDbId,10),i=this.sessions.get(t);if(!i){r.status(404).json({error:"Session not found"});return}ie.warn("WORKER","Session delete requested",{sessionId:t}),i.abortController.abort(),i.generatorPromise&&await Promise.race([i.generatorPromise,new Promise(n=>setTimeout(n,5e3))]);let s=new nt;s.markSessionFailed(t),s.close(),this.sessions.delete(t),ie.info("WORKER","Session deleted",{sessionId:t}),r.json({status:"deleted"})}async runSDKAgent(e){ie.info("SDK","Agent starting",{sessionId:e.sessionDbId});let r=process.env.CLAUDE_CODE_PATH||"/Users/alexnewman/.nvm/versions/node/v24.5.0/bin/claude";try{let t=lg({prompt:this.createMessageGenerator(e),options:{model:Q2,disallowedTools:J2,abortController:e.abortController,pathToClaudeCodeExecutable:r}});for await(let n of t)if(n.type==="system"&&n.subtype==="init"){let o=n;if(o.session_id){let p=new nt,c=p.updateSDKSessionId(e.sessionDbId,o.session_id);p.close(),c&&(ie.success("SDK","Session initialized",{sessionId:e.sessionDbId,sdkSessionId:o.session_id}),e.sdkSessionId=o.session_id)}}else if(n.type==="assistant"){let o=n.message.content,p=Array.isArray(o)?o.filter(l=>l.type==="text").map(l=>l.text).join(` `):typeof o=="string"?o:"",c=p.length;ie.dataOut("SDK",`Response received (${c} chars)`,{sessionId:e.sessionDbId,promptNumber:e.lastPromptNumber}),ie.debug("SDK","Full response",{sessionId:e.sessionDbId},p),this.handleAgentMessage(e,p,e.lastPromptNumber)}let i=Date.now()-e.startTime;ie.success("SDK","Agent completed",{sessionId:e.sessionDbId,duration:`${(i/1e3).toFixed(1)}s`});let s=new nt;s.markSessionCompleted(e.sessionDbId),s.close(),this.sessions.delete(e.sessionDbId)}catch(t){throw t.name==="AbortError"?ie.warn("SDK","Agent aborted",{sessionId:e.sessionDbId}):ie.failure("SDK","Agent error",{sessionId:e.sessionDbId},t),t}}async*createMessageGenerator(e){let r=hg(e.project,e.claudeSessionId,e.userPrompt);for(ie.dataIn("SDK",`Init prompt sent (${r.length} chars)`,{sessionId:e.sessionDbId,claudeSessionId:e.claudeSessionId,project:e.project}),ie.debug("SDK","Full init prompt",{sessionId:e.sessionDbId},r),yield{type:"user",session_id:e.claudeSessionId,parent_tool_use_id:null,message:{role:"user",content:r}};!e.abortController.signal.aborted;){if(e.pendingMessages.length===0){await new Promise(t=>setTimeout(t,100));continue}for(;e.pendingMessages.length>0;){let t=e.pendingMessages.shift();if(t.type==="summarize"){e.lastPromptNumber=t.prompt_number;let i=new nt,s=i.getSessionById(e.sessionDbId);if(i.close(),s){let n=gg(s);ie.dataIn("SDK",`Summary prompt sent (${n.length} chars)`,{sessionId:e.sessionDbId,promptNumber:t.prompt_number}),ie.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(t.type==="observation"){e.lastPromptNumber=t.prompt_number;let i=vg({id:0,tool_name:t.tool_name,tool_input:t.tool_input,tool_output:t.tool_output,created_at_epoch:Date.now()}),s=ie.formatTool(t.tool_name,t.tool_input),n=ie.correlationId(e.sessionDbId,e.observationCounter);ie.dataIn("SDK",`Observation prompt: ${s}`,{correlationId:n,promptNumber:t.prompt_number,size:`${i.length} chars`}),ie.debug("SDK","Full observation prompt",{correlationId:n},i),yield{type:"user",session_id:e.claudeSessionId,parent_tool_use_id:null,message:{role:"user",content:i}}}}}}handleAgentMessage(e,r,t){let i=ie.correlationId(e.sessionDbId,e.observationCounter),s=xg(r,i);s.length>0&&ie.info("PARSER",`Parsed ${s.length} observation(s)`,{correlationId:i,promptNumber:t,types:s.map(p=>p.type).join(", ")});let n=new nt;for(let p of s)e.sdkSessionId&&(n.storeObservation(e.sdkSessionId,e.project,p,t),ie.success("DB","Observation stored",{correlationId:i,type:p.type,title:p.title}));let o=yg(r,e.sessionDbId);o&&e.sdkSessionId&&(ie.info("PARSER","Summary parsed",{sessionId:e.sessionDbId,promptNumber:t}),n.storeSummary(e.sdkSessionId,e.project,o,t),ie.success("DB","Summary stored",{sessionId:e.sessionDbId})),n.close()}};async function Y2(){await new us().start(),process.on("SIGINT",()=>{ie.warn("SYSTEM","Shutting down (SIGINT)"),process.exit(0)}),process.on("SIGTERM",()=>{ie.warn("SYSTEM","Shutting down (SIGTERM)"),process.exit(0)})}Y2().catch(a=>{ie.failure("SYSTEM","Fatal startup error",{},a),process.exit(1)});0&&(module.exports={WorkerService}); /*! Bundled license information: diff --git a/src/sdk/prompts.ts b/src/sdk/prompts.ts index d9d2e710..39325749 100644 --- a/src/sdk/prompts.ts +++ b/src/sdk/prompts.ts @@ -164,12 +164,6 @@ IMPORTANT! DO NOT summarize the observation process itself - you are summarizing User's Original Request: ${session.user_prompt} -WHEN NOT TO SUMMARIZE ----------------------- -Do not summarize if the request is conversational and unrelated to the work that was just completed. - -If skipping, **output only**: - ✅ GOOD - Describes deliverables: Fix authentication timeout bug Add three-tier verbosity system to session summaries @@ -182,14 +176,17 @@ If skipping, **output only**: Output this XML: - [What did the user request? Use their original sentiment from: ${session.user_prompt}] + [What did the user request? Form a title that reflects the actual request: ${session.user_prompt}] [What was explored?] - [What was discovered about how things work?] + [What was learned about how things work?] [What shipped? What does the system now do?] [What are the next steps?] [Additional insights] **Required fields**: request, investigated, learned, completed, next_steps -**Optional fields**: notes`; +**Optional fields**: notes + +IMPORTANT: This is not the end of the session. You will receive more requests to process, and more tool usages to observe and record. The summary helps keep track of progress. +`; }