primocode 7.0.2 → 7.0.3

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.
Files changed (3) hide show
  1. package/lib/act.js +58 -9
  2. package/lib/api.js +3 -3
  3. package/package.json +1 -1
package/lib/act.js CHANGED
@@ -2,9 +2,12 @@
2
2
 
3
3
  'use strict';
4
4
 
5
+ const fs = require('fs');
6
+ const path = require('path');
5
7
  const { c, actionHeader, Spinner } = require('./ui');
6
8
  const tools = require('./tools');
7
9
  const api = require('./api');
10
+ const { ROOT_DIR } = require('./config');
8
11
 
9
12
  const MAX_ITERATIONS = 15;
10
13
 
@@ -28,13 +31,58 @@ function makeLogger() {
28
31
  };
29
32
  }
30
33
 
34
+ function readMemory(projectDir, projectName) {
35
+ let context = '';
36
+
37
+ // Ler you.md (memória geral)
38
+ const youMdPath = path.join(ROOT_DIR, 'you.md');
39
+ if (fs.existsSync(youMdPath)) {
40
+ try {
41
+ const youContent = fs.readFileSync(youMdPath, 'utf-8');
42
+ context += `[Memória Geral (you.md)]\n${youContent.slice(0, 2000)}\n\n`;
43
+ } catch {}
44
+ }
45
+
46
+ // Ler memory.md do projeto
47
+ if (projectDir && projectName) {
48
+ const memoryPath = path.join(projectDir, 'memory.md');
49
+ if (fs.existsSync(memoryPath)) {
50
+ try {
51
+ const memContent = fs.readFileSync(memoryPath, 'utf-8');
52
+ context += `[Memória do Projeto: ${projectName}]\n${memContent.slice(0, 2000)}\n\n`;
53
+ } catch {}
54
+ }
55
+ }
56
+
57
+ return context;
58
+ }
59
+
60
+ function updateMemory(projectDir, projectName, entry) {
61
+ if (!projectDir || !projectName) return;
62
+ const memoryPath = path.join(projectDir, 'memory.md');
63
+ try {
64
+ let content = '';
65
+ if (fs.existsSync(memoryPath)) {
66
+ content = fs.readFileSync(memoryPath, 'utf-8');
67
+ }
68
+ const timestamp = new Date().toISOString().split('T')[0];
69
+ content += `\n## ${timestamp}\n${entry}\n`;
70
+ fs.writeFileSync(memoryPath, content, 'utf-8');
71
+ } catch {}
72
+ }
73
+
31
74
  async function runAct(userPrompt, opts) {
32
75
  const { server, model, history, projectDir, projectName } = opts || {};
33
76
  const logger = makeLogger();
34
- const messages = [
35
- ...(Array.isArray(history) ? history.filter(m => m && m.role && m.content).slice(-20) : []),
36
- { role: 'user', content: userPrompt },
37
- ];
77
+
78
+ // Ler memórias
79
+ const memoryContext = readMemory(projectDir, projectName);
80
+
81
+ // Montar prompt com contexto de memória
82
+ const fullPrompt = memoryContext
83
+ ? `[Contexto de memória]\n${memoryContext}\n[Tarefa]\n${userPrompt}`
84
+ : userPrompt;
85
+
38
86
  const toolResults = [];
39
87
  let iteration = 0;
40
88
  let plan = '';
@@ -45,7 +93,7 @@ async function runAct(userPrompt, opts) {
45
93
  const sp = new Spinner('Primo Code pensando').start();
46
94
 
47
95
  try {
48
- await api.requestAct(server, messages, model, { projectDir, projectName, plan_cache: plan }, (evt) => {
96
+ await api.requestAct(server, fullPrompt, history, model, { projectDir, projectName, plan_cache: plan, tool_results: toolResults }, (evt) => {
49
97
  if (evt.plan) {
50
98
  plan = evt.plan;
51
99
  }
@@ -76,15 +124,14 @@ async function runAct(userPrompt, opts) {
76
124
  // Se não teve tool_calls, mostrar conteúdo
77
125
  if (toolResults.length === 0 && assistantContent) {
78
126
  console.log('\n' + c.white(assistantContent));
127
+ // Atualizar memória
128
+ updateMemory(projectDir, projectName, `Tarefa: ${userPrompt}\nResultado: ${assistantContent.slice(0, 500)}`);
79
129
  return { userMessage: { role: 'user', content: userPrompt }, assistantMessage: { role: 'assistant', content: assistantContent } };
80
130
  }
81
131
 
82
132
  // Se teve tool_results, enviar de volta para próximo turno
83
133
  if (toolResults.length > 0) {
84
- messages.push({ role: 'assistant', content: assistantContent, tool_calls: [] });
85
- for (const tr of toolResults) {
86
- messages.push({ role: 'tool', tool_call_id: tr.tool_call_id, content: JSON.stringify(tr.result) });
87
- }
134
+ // Limpar para próximo turno
88
135
  toolResults.length = 0;
89
136
  assistantContent = '';
90
137
  continue;
@@ -98,6 +145,8 @@ async function runAct(userPrompt, opts) {
98
145
  }
99
146
  }
100
147
 
148
+ // Atualizar memória
149
+ updateMemory(projectDir, projectName, `Tarefa: ${userPrompt}\nResultado: Concluído`);
101
150
  return { userMessage: { role: 'user', content: userPrompt }, assistantMessage: { role: 'assistant', content: assistantContent || 'Concluído.' } };
102
151
  }
103
152
 
package/lib/api.js CHANGED
@@ -30,9 +30,9 @@ function requestStream(serverUrl, endpoint, payload, onEvent) {
30
30
  });
31
31
  }
32
32
 
33
- function requestAct(serverUrl, messages, model, extras, onEvent) {
34
- // Usa streaming para /api/act/stream
35
- return requestStream(serverUrl, '/api/act/stream', { messages, model, ...(extras || {}) }, onEvent);
33
+ function requestAct(serverUrl, prompt, history, model, extras, onEvent) {
34
+ // Envia prompt (string) e history (array) separados para /api/act/stream
35
+ return requestStream(serverUrl, '/api/act/stream', { prompt, history, model, ...(extras || {}) }, onEvent);
36
36
  }
37
37
 
38
38
  function getHealth(serverUrl) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "primocode",
3
- "version": "7.0.2",
3
+ "version": "7.0.3",
4
4
  "description": "PrimoCode \u2014 agente de engenharia com IA e cursor pr\u00f3prio. Modo primocode cria arquivos, controla o desktop e navegador. Modo chat \u00e9 conversa pura.",
5
5
  "main": "bin/primocode.js",
6
6
  "bin": "./bin/primocode.js",