tempo-agent 1.1.0 → 1.3.0
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.
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Tempo [](https://www.npmjs.org/package/tempo-agent)
|
|
2
2
|
|
|
3
|
-
AI-driven code generation CLI. Give Tempo a goal, and it writes, validates, and retries code changes step by step
|
|
3
|
+
AI-driven code generation CLI. Give Tempo a goal, and it writes, validates, and retries code changes step by step.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -10,23 +10,25 @@ npm install -g tempo-agent
|
|
|
10
10
|
|
|
11
11
|
## Requirements
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Tempo uses the **Gemini 2.0 Flash** model via the Google AI API (free tier available — no billing required).
|
|
14
|
+
|
|
15
|
+
Set your Gemini API key as an environment variable.
|
|
14
16
|
|
|
15
17
|
**macOS / Linux**
|
|
16
18
|
```bash
|
|
17
|
-
export
|
|
19
|
+
export GEMINI_API_KEY=your-key-here
|
|
18
20
|
```
|
|
19
21
|
|
|
20
22
|
**Windows (PowerShell)**
|
|
21
23
|
```powershell
|
|
22
24
|
# Current session only
|
|
23
|
-
$env:
|
|
25
|
+
$env:GEMINI_API_KEY = "your-key-here"
|
|
24
26
|
|
|
25
27
|
# Permanently (no need to set it again after restart)
|
|
26
|
-
[System.Environment]::SetEnvironmentVariable("
|
|
28
|
+
[System.Environment]::SetEnvironmentVariable("GEMINI_API_KEY", "your-key-here", "User")
|
|
27
29
|
```
|
|
28
30
|
|
|
29
|
-
Get your API key at [
|
|
31
|
+
Get your free API key at [aistudio.google.com](https://aistudio.google.com) → Get API Key.
|
|
30
32
|
|
|
31
33
|
## Usage
|
|
32
34
|
|
|
@@ -73,7 +75,7 @@ Generates `.tempo/scores/my-feature.json` — a structured execution plan.
|
|
|
73
75
|
|
|
74
76
|
### 4. Edit the Score
|
|
75
77
|
|
|
76
|
-
Open `.tempo/scores/my-feature.json` and fill in `files_allowed` for each Step — the list of files
|
|
78
|
+
Open `.tempo/scores/my-feature.json` and fill in `files_allowed` for each Step — the list of files Tempo is permitted to create or modify:
|
|
77
79
|
|
|
78
80
|
```json
|
|
79
81
|
{
|
|
@@ -120,7 +122,7 @@ Every run is saved to `.tempo/sessions/session-{timestamp}/`:
|
|
|
120
122
|
|
|
121
123
|
| File | Contents |
|
|
122
124
|
|---|---|
|
|
123
|
-
| `step-N.md` | Prompt sent, files used,
|
|
125
|
+
| `step-N.md` | Prompt sent, files used, AI response, result |
|
|
124
126
|
| `errors-step-N.md` | Validation errors and retry attempts |
|
|
125
127
|
| `diff-N.patch` | Git diff after each Step |
|
|
126
128
|
|
|
@@ -134,8 +136,8 @@ Add to your `.gitignore`:
|
|
|
134
136
|
## How it works
|
|
135
137
|
|
|
136
138
|
1. Reads the files listed in `files_allowed` for the current Step
|
|
137
|
-
2. Sends them to
|
|
138
|
-
3.
|
|
139
|
+
2. Sends them to Gemini with the Step instruction
|
|
140
|
+
3. Gemini returns full file replacements
|
|
139
141
|
4. Tempo writes them to disk
|
|
140
|
-
5. Runs validation — if it fails, sends the errors back to
|
|
142
|
+
5. Runs validation — if it fails, sends the errors back to Gemini and retries
|
|
141
143
|
6. Moves to the next Step once validation passes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claudeClient.d.ts","sourceRoot":"","sources":["../../src/executor/claudeClient.ts"],"names":[],"mappings":"AAKA,wBAAsB,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"claudeClient.d.ts","sourceRoot":"","sources":["../../src/executor/claudeClient.ts"],"names":[],"mappings":"AAKA,wBAAsB,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiC1F"}
|
|
@@ -5,29 +5,35 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.callClaude = callClaude;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
|
-
const
|
|
9
|
-
const
|
|
8
|
+
const GEMINI_MODEL = 'gemini-2.0-flash';
|
|
9
|
+
const GEMINI_API_URL = `https://generativelanguage.googleapis.com/v1beta/models/${GEMINI_MODEL}:generateContent`;
|
|
10
10
|
async function callClaude(systemPrompt, userPrompt) {
|
|
11
|
-
const apiKey = process.env.
|
|
11
|
+
const apiKey = process.env.GEMINI_API_KEY;
|
|
12
12
|
if (!apiKey) {
|
|
13
|
-
throw new Error('
|
|
13
|
+
throw new Error('GEMINI_API_KEY environment variable is not set');
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
'
|
|
23
|
-
|
|
24
|
-
'content-type': 'application/json',
|
|
25
|
-
},
|
|
26
|
-
});
|
|
27
|
-
const block = response.data.content?.[0];
|
|
28
|
-
if (!block || block.type !== 'text') {
|
|
29
|
-
throw new Error('Unexpected response format from Claude API');
|
|
15
|
+
let response;
|
|
16
|
+
try {
|
|
17
|
+
response = await axios_1.default.post(`${GEMINI_API_URL}?key=${apiKey}`, {
|
|
18
|
+
systemInstruction: { parts: [{ text: systemPrompt }] },
|
|
19
|
+
contents: [{ role: 'user', parts: [{ text: userPrompt }] }],
|
|
20
|
+
generationConfig: { maxOutputTokens: 8192 },
|
|
21
|
+
}, {
|
|
22
|
+
headers: { 'content-type': 'application/json' },
|
|
23
|
+
});
|
|
30
24
|
}
|
|
31
|
-
|
|
25
|
+
catch (err) {
|
|
26
|
+
const axiosErr = err;
|
|
27
|
+
if (axiosErr.response) {
|
|
28
|
+
const body = JSON.stringify(axiosErr.response.data);
|
|
29
|
+
throw new Error(`API error ${axiosErr.response.status}: ${body}`);
|
|
30
|
+
}
|
|
31
|
+
throw err;
|
|
32
|
+
}
|
|
33
|
+
const text = response.data.candidates?.[0]?.content?.parts?.[0]?.text;
|
|
34
|
+
if (typeof text !== 'string') {
|
|
35
|
+
throw new Error('Unexpected response format from Gemini API');
|
|
36
|
+
}
|
|
37
|
+
return text;
|
|
32
38
|
}
|
|
33
39
|
//# sourceMappingURL=claudeClient.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claudeClient.js","sourceRoot":"","sources":["../../src/executor/claudeClient.ts"],"names":[],"mappings":";;;;;AAKA,
|
|
1
|
+
{"version":3,"file":"claudeClient.js","sourceRoot":"","sources":["../../src/executor/claudeClient.ts"],"names":[],"mappings":";;;;;AAKA,gCAiCC;AAtCD,kDAA0C;AAE1C,MAAM,YAAY,GAAG,kBAAkB,CAAC;AACxC,MAAM,cAAc,GAAG,2DAA2D,YAAY,kBAAkB,CAAC;AAE1G,KAAK,UAAU,UAAU,CAAC,YAAoB,EAAE,UAAkB;IACvE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,QAAQ,CAAC;IACb,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,eAAK,CAAC,IAAI,CACzB,GAAG,cAAc,QAAQ,MAAM,EAAE,EACjC;YACE,iBAAiB,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE;YACtD,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;YAC3D,gBAAgB,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;SAC5C,EACD;YACE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;SAChD,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,QAAQ,GAAG,GAAiB,CAAC;QACnC,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACtB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,aAAa,QAAQ,CAAC,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;IACtE,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|