@almightygpt/core 0.3.0 → 0.5.1
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/dist/adapters/claude.d.ts +1 -1
- package/dist/adapters/claude.d.ts.map +1 -1
- package/dist/adapters/claude.js +46 -6
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/gemini.d.ts +1 -1
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js.map +1 -1
- package/dist/adapters/mock.d.ts +1 -0
- package/dist/adapters/mock.d.ts.map +1 -1
- package/dist/adapters/mock.js +1 -0
- package/dist/adapters/mock.js.map +1 -1
- package/dist/adapters/openai.d.ts +1 -1
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +20 -5
- package/dist/adapters/openai.js.map +1 -1
- package/dist/adapters/types.d.ts +20 -2
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/git/status.d.ts.map +1 -1
- package/dist/git/status.js +18 -5
- package/dist/git/status.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/review/diff-filter.d.ts +37 -0
- package/dist/review/diff-filter.d.ts.map +1 -0
- package/dist/review/diff-filter.js +144 -0
- package/dist/review/diff-filter.js.map +1 -0
- package/dist/review/events.d.ts +2 -0
- package/dist/review/events.d.ts.map +1 -1
- package/dist/review/run-diff-review.d.ts +2 -0
- package/dist/review/run-diff-review.d.ts.map +1 -1
- package/dist/review/run-diff-review.js +34 -8
- package/dist/review/run-diff-review.js.map +1 -1
- package/dist/review/run-worker-reviewer.d.ts.map +1 -1
- package/dist/review/run-worker-reviewer.js +43 -10
- package/dist/review/run-worker-reviewer.js.map +1 -1
- package/dist/review/write.d.ts +15 -0
- package/dist/review/write.d.ts.map +1 -1
- package/dist/review/write.js +29 -0
- package/dist/review/write.js.map +1 -1
- package/dist/runs/types.d.ts +6 -0
- package/dist/runs/types.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/adapters/claude.ts +59 -8
- package/src/adapters/gemini.ts +1 -1
- package/src/adapters/mock.ts +1 -0
- package/src/adapters/openai.ts +35 -7
- package/src/adapters/types.ts +20 -2
- package/src/git/status.ts +21 -5
- package/src/index.ts +3 -1
- package/src/review/diff-filter.ts +190 -0
- package/src/review/events.ts +2 -0
- package/src/review/run-diff-review.ts +46 -8
- package/src/review/run-worker-reviewer.ts +53 -10
- package/src/review/write.ts +42 -0
- package/src/runs/types.ts +6 -0
package/dist/review/write.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/review/write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAED;IAD3B,IAAI,GAAG,uBAAuB,CAAC;IACjD,YAAY,OAAe,EAAkB,IAAY;QACvD,KAAK,CAAC,OAAO,CAAC,CAAC;QAD4B,SAAI,GAAJ,IAAI,CAAQ;IAEzD,CAAC;CACF;AA8BD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAA4B;IAE5B,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,SAAS,KAAK,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAE7C,uEAAuE;IACvE,yEAAyE;IACzE,0EAA0E;IAC1E,0EAA0E;IAC1E,0DAA0D;IAC1D,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACvC,oEAAoE;QACpE,uEAAuE;QACvE,MAAM,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QACvD,MAAM,IAAI,qBAAqB,CAC7B,yBAAyB,OAAO,mCAAmC;YACjE,iEAAiE;YACjE,yCAAyC,EAC3C,OAAO,CACR,CAAC;IACJ,CAAC;IAED,0EAA0E;IAC1E,0EAA0E;IAC1E,MAAM,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAE5D,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEnD,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAE1C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;AAClD,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,wEAAwE;IACxE,+DAA+D;IAC/D,MAAM,OAAO,GAAG,KAAK;SAClB,IAAI,EAAE;SACN,WAAW,EAAE;SACb,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC;SAC9B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC3B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,UAAU,KAAK,wDAAwD;YACrE,sCAAsC,CACzC,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,oBAAoB,CAAC,IAA4B;IACxD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7C,MAAM,WAAW,GAAG;QAClB,aAAa,IAAI,CAAC,KAAK,EAAE;QACzB,EAAE;QACF,iBAAiB,IAAI,CAAC,YAAY,OAAO,IAAI,CAAC,gBAAgB,KAAK,IAAI,CAAC,SAAS,KAAK;QACtF,gBAAgB,GAAG,IAAI;QACvB,aAAa,IAAI,CAAC,OAAO,CAAC,QAAQ,SAAS,IAAI,CAAC,OAAO,CAAC,SAAS,QAAQ;QACzE,YAAY,IAAI,QAAQ;QACxB,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;QAC7D,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,mBAAmB,IAAI,CAAC,SAAS,MAAM,CAAC,CAAC,CAAC,EAAE;QAC7D,EAAE;KACH,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAEhE,MAAM,QAAQ,GAAa,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAEpD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CACX;YACE,kCAAkC;YAClC,GAAG;YACH,KAAK,IAAI,CAAC,cAAc,EAAE;YAC1B,GAAG;YACH,2DAA2D;YAC3D,EAAE;SACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC;IAED,sEAAsE;IACtE,4DAA4D;IAC5D,IAAI,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACjC,SAAS,GAAG,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAChD,SAAS,GAAG,yBAAyB,CAAC,SAAS,CAAC,CAAC;IACjD,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEzB,uEAAuE;IACvE,2DAA2D;IAC3D,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,QAAQ,CAAC,IAAI,CACX;YACE,EAAE;YACF,0BAA0B;YAC1B,EAAE;YACF,mBAAmB,IAAI,CAAC,SAAS,KAAK;YACtC,sCAAsC,IAAI,CAAC,SAAS,sBAAsB;YAC1E,8BAA8B,IAAI,CAAC,SAAS,wBAAwB;YACpE,yBAAyB,IAAI,CAAC,SAAS,0BAA0B;YACjE,yBAAyB,IAAI,CAAC,SAAS,aAAa;YACpD,qBAAqB,IAAI,CAAC,SAAS,aAAa;SACjD,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC;IAED,QAAQ,CAAC,IAAI,CACX;QACE,EAAE;QACF,KAAK;QACL,+HAA+H;KAChI,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,IAAY,EAAE,KAAa;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,+DAA+D;IAC/D,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACvB,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,uDAAuD;YACvD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,KAAK,EAAE;gBAAE,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/D,SAAS;QACX,CAAC;QACD,MAAM;IACR,CAAC;IACD,oEAAoE;IACpE,4EAA4E;IAC5E,KAAK,KAAK,CAAC;IACX,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,yBAAyB,CAAC,IAAY;IAC7C,MAAM,cAAc,GAClB,8FAA8F,CAAC;IACjG,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;AACpD,CAAC"}
|
|
1
|
+
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/review/write.ts"],"names":[],"mappings":"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"}
|
package/dist/runs/types.d.ts
CHANGED
|
@@ -17,6 +17,12 @@ export interface AgentMetrics {
|
|
|
17
17
|
provider: string;
|
|
18
18
|
model: string;
|
|
19
19
|
tokensIn: number;
|
|
20
|
+
/**
|
|
21
|
+
* Portion of tokensIn served from the provider's prompt cache (Anthropic
|
|
22
|
+
* cache_read, OpenAI prompt_tokens_details.cached_tokens). Always less
|
|
23
|
+
* than or equal to tokensIn. Zero when caching didn't trigger.
|
|
24
|
+
*/
|
|
25
|
+
cachedTokensIn?: number;
|
|
20
26
|
tokensOut: number;
|
|
21
27
|
costUsd: number;
|
|
22
28
|
latencyMs: number;
|
package/dist/runs/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runs/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,OAAO,GACf,aAAa,GACb,aAAa,GACb,oBAAoB,GACpB,wBAAwB,CAAC;AAE7B,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,gBAAgB,CAAC;AAE9E,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,EAAE,EAAE,MAAM,CAAC;IACX,mBAAmB;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,GAAG,CAAC,EAAE;QACJ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,+BAA+B;IAC/B,KAAK,EAAE;QACL,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,MAAM,GAAG,kBAAkB,GAAG,KAAK,CAAC;QACpE,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,sDAAsD;IACtD,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;IAC7E,gCAAgC;IAChC,eAAe,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACxD,oBAAoB;IACpB,MAAM,EAAE,SAAS,CAAC;IAClB,yBAAyB;IACzB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,wBAAwB;IACxB,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,+CAA+C;IAC/C,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,uCAAuC;IACvC,MAAM,EAAE;QACN,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,wDAAwD;IACxD,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,MAAM,cAAc,GACtB,UAAU,GACV,eAAe,GACf,UAAU,GACV,UAAU,CAAC;AAEf,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runs/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@almightygpt/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Core orchestrator, adapters, config, runs, and review logic for AlmightyGPT",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"@anthropic-ai/sdk": "^0.30.0",
|
|
27
27
|
"@google/generative-ai": "^0.21.0",
|
|
28
28
|
"execa": "^9.3.0",
|
|
29
|
+
"ignore": "^6.0.2",
|
|
29
30
|
"openai": "^4.52.0",
|
|
30
31
|
"p-limit": "^5.0.0",
|
|
31
32
|
"yaml": "^2.4.0",
|
package/src/adapters/claude.ts
CHANGED
|
@@ -39,7 +39,7 @@ export class ClaudeAdapter implements Adapter {
|
|
|
39
39
|
readonly provider = "anthropic";
|
|
40
40
|
|
|
41
41
|
private readonly client: Anthropic | null;
|
|
42
|
-
|
|
42
|
+
readonly defaultModel: string;
|
|
43
43
|
private readonly defaultMaxOutputTokens: number;
|
|
44
44
|
private readonly defaultTimeoutMs: number;
|
|
45
45
|
|
|
@@ -76,7 +76,23 @@ export class ClaudeAdapter implements Adapter {
|
|
|
76
76
|
{
|
|
77
77
|
model,
|
|
78
78
|
max_tokens: maxOutputTokens,
|
|
79
|
-
system:
|
|
79
|
+
// Pass system as a content-block array with cache_control:
|
|
80
|
+
// ephemeral on the (only) block. Anthropic caches the marked
|
|
81
|
+
// block for ~5 minutes; subsequent calls with the same prefix
|
|
82
|
+
// get charged at 10% of normal input rate for the cached span.
|
|
83
|
+
// The CLI's review flow re-sends the same memory (AGENTS.md +
|
|
84
|
+
// CODEX_AGENT.md + rules.md) on every run, so this is a near-
|
|
85
|
+
// perfect fit.
|
|
86
|
+
// cache_control isn't in the SDK 0.30.x .d.ts yet but the
|
|
87
|
+
// v1/messages API accepts it. Cast at the call site.
|
|
88
|
+
system: [
|
|
89
|
+
{
|
|
90
|
+
type: "text",
|
|
91
|
+
text: input.systemPrompt,
|
|
92
|
+
cache_control: { type: "ephemeral" },
|
|
93
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
94
|
+
} as any,
|
|
95
|
+
],
|
|
80
96
|
messages: [{ role: "user", content: input.userMessage }],
|
|
81
97
|
},
|
|
82
98
|
{ timeout: timeoutMs },
|
|
@@ -102,13 +118,36 @@ export class ClaudeAdapter implements Adapter {
|
|
|
102
118
|
);
|
|
103
119
|
}
|
|
104
120
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
121
|
+
// Anthropic usage fields with caching enabled:
|
|
122
|
+
// input_tokens — fresh-hit input tokens (full price)
|
|
123
|
+
// cache_creation_input_tokens — tokens that just got written to the
|
|
124
|
+
// cache (1.25× of normal rate, one-time)
|
|
125
|
+
// cache_read_input_tokens — tokens served from existing cache
|
|
126
|
+
// (0.1× of normal rate)
|
|
127
|
+
// We surface cache_read as `cachedTokensIn`. Cache-creation tokens are
|
|
128
|
+
// folded into `tokensIn` total for visibility and cost-modeled at the
|
|
129
|
+
// normal rate (close enough — the 25% surcharge is small relative to
|
|
130
|
+
// the savings on subsequent reads).
|
|
131
|
+
const usage = response.usage as Anthropic.Usage & {
|
|
132
|
+
cache_creation_input_tokens?: number;
|
|
133
|
+
cache_read_input_tokens?: number;
|
|
134
|
+
};
|
|
135
|
+
const freshIn = usage.input_tokens;
|
|
136
|
+
const cacheCreationIn = usage.cache_creation_input_tokens ?? 0;
|
|
137
|
+
const cacheReadIn = usage.cache_read_input_tokens ?? 0;
|
|
138
|
+
const tokensIn = freshIn + cacheCreationIn + cacheReadIn;
|
|
139
|
+
const tokensOut = usage.output_tokens;
|
|
140
|
+
const costUsd = estimateCostUsdWithCache(
|
|
141
|
+
model,
|
|
142
|
+
freshIn + cacheCreationIn, // both billed at ~normal input rate
|
|
143
|
+
cacheReadIn,
|
|
144
|
+
tokensOut,
|
|
145
|
+
);
|
|
108
146
|
|
|
109
147
|
return {
|
|
110
148
|
content,
|
|
111
149
|
tokensIn,
|
|
150
|
+
cachedTokensIn: cacheReadIn,
|
|
112
151
|
tokensOut,
|
|
113
152
|
costUsd,
|
|
114
153
|
latencyMs: Date.now() - start,
|
|
@@ -118,9 +157,17 @@ export class ClaudeAdapter implements Adapter {
|
|
|
118
157
|
}
|
|
119
158
|
}
|
|
120
159
|
|
|
121
|
-
|
|
160
|
+
/**
|
|
161
|
+
* Anthropic cache read discount: cache_read_input_tokens are charged at
|
|
162
|
+
* roughly 10% of normal input rate. (See
|
|
163
|
+
* https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching.)
|
|
164
|
+
*/
|
|
165
|
+
const CACHE_READ_DISCOUNT = 0.1;
|
|
166
|
+
|
|
167
|
+
function estimateCostUsdWithCache(
|
|
122
168
|
model: string,
|
|
123
|
-
|
|
169
|
+
freshOrCreationIn: number,
|
|
170
|
+
cacheReadIn: number,
|
|
124
171
|
tokensOut: number,
|
|
125
172
|
): number {
|
|
126
173
|
const key = Object.keys(PRICING_USD_PER_1M).find((k) =>
|
|
@@ -129,5 +176,9 @@ function estimateCostUsd(
|
|
|
129
176
|
if (!key) return 0;
|
|
130
177
|
const rates = PRICING_USD_PER_1M[key];
|
|
131
178
|
if (!rates) return 0;
|
|
132
|
-
return (
|
|
179
|
+
return (
|
|
180
|
+
(freshOrCreationIn / 1_000_000) * rates.input +
|
|
181
|
+
(cacheReadIn / 1_000_000) * rates.input * CACHE_READ_DISCOUNT +
|
|
182
|
+
(tokensOut / 1_000_000) * rates.output
|
|
183
|
+
);
|
|
133
184
|
}
|
package/src/adapters/gemini.ts
CHANGED
|
@@ -59,7 +59,7 @@ export class GeminiAdapter implements Adapter {
|
|
|
59
59
|
readonly provider = "google";
|
|
60
60
|
|
|
61
61
|
private readonly client: GoogleGenerativeAI | null;
|
|
62
|
-
|
|
62
|
+
readonly defaultModel: string;
|
|
63
63
|
private readonly defaultMaxOutputTokens: number;
|
|
64
64
|
private readonly defaultTimeoutMs: number;
|
|
65
65
|
|
package/src/adapters/mock.ts
CHANGED
|
@@ -12,6 +12,7 @@ import type { Adapter, AdapterInput, AdapterOutput } from "./types.js";
|
|
|
12
12
|
export class MockAdapter implements Adapter {
|
|
13
13
|
readonly name = "mock";
|
|
14
14
|
readonly provider = "mock";
|
|
15
|
+
readonly defaultModel = "mock-1";
|
|
15
16
|
|
|
16
17
|
constructor(
|
|
17
18
|
private readonly opts: {
|
package/src/adapters/openai.ts
CHANGED
|
@@ -43,7 +43,7 @@ export class OpenAIAdapter implements Adapter {
|
|
|
43
43
|
readonly provider = "openai";
|
|
44
44
|
|
|
45
45
|
private readonly client: OpenAI | null;
|
|
46
|
-
|
|
46
|
+
readonly defaultModel: string;
|
|
47
47
|
private readonly defaultMaxOutputTokens: number;
|
|
48
48
|
private readonly defaultTimeoutMs: number;
|
|
49
49
|
|
|
@@ -118,13 +118,30 @@ export class OpenAIAdapter implements Adapter {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
const content = choice.message.content;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
// OpenAI prompt caching is automatic for prompts > 1024 tokens; the
|
|
122
|
+
// cached span is the longest common prefix across recent calls with
|
|
123
|
+
// the same model. The fraction cached comes back in
|
|
124
|
+
// prompt_tokens_details.cached_tokens. Cache reads are billed at ~50%
|
|
125
|
+
// of normal input rate.
|
|
126
|
+
const usage = response.usage as
|
|
127
|
+
| (typeof response.usage & {
|
|
128
|
+
prompt_tokens_details?: { cached_tokens?: number };
|
|
129
|
+
})
|
|
130
|
+
| undefined;
|
|
131
|
+
const tokensIn = usage?.prompt_tokens ?? 0;
|
|
132
|
+
const cacheReadIn = usage?.prompt_tokens_details?.cached_tokens ?? 0;
|
|
133
|
+
const tokensOut = usage?.completion_tokens ?? 0;
|
|
134
|
+
const costUsd = estimateCostUsdWithCache(
|
|
135
|
+
model,
|
|
136
|
+
tokensIn - cacheReadIn,
|
|
137
|
+
cacheReadIn,
|
|
138
|
+
tokensOut,
|
|
139
|
+
);
|
|
124
140
|
|
|
125
141
|
return {
|
|
126
142
|
content,
|
|
127
143
|
tokensIn,
|
|
144
|
+
cachedTokensIn: cacheReadIn,
|
|
128
145
|
tokensOut,
|
|
129
146
|
costUsd,
|
|
130
147
|
latencyMs: Date.now() - start,
|
|
@@ -134,9 +151,16 @@ export class OpenAIAdapter implements Adapter {
|
|
|
134
151
|
}
|
|
135
152
|
}
|
|
136
153
|
|
|
137
|
-
|
|
154
|
+
/**
|
|
155
|
+
* OpenAI cache-read discount: cached input tokens are billed at 50% of
|
|
156
|
+
* normal input rate. (See https://platform.openai.com/docs/guides/prompt-caching.)
|
|
157
|
+
*/
|
|
158
|
+
const CACHE_READ_DISCOUNT = 0.5;
|
|
159
|
+
|
|
160
|
+
function estimateCostUsdWithCache(
|
|
138
161
|
model: string,
|
|
139
|
-
|
|
162
|
+
freshTokensIn: number,
|
|
163
|
+
cacheReadIn: number,
|
|
140
164
|
tokensOut: number,
|
|
141
165
|
): number {
|
|
142
166
|
// Match by prefix so versioned model names (gpt-4o-2024-08-06) still resolve.
|
|
@@ -146,5 +170,9 @@ function estimateCostUsd(
|
|
|
146
170
|
if (!key) return 0;
|
|
147
171
|
const rates = PRICING_USD_PER_1M[key];
|
|
148
172
|
if (!rates) return 0;
|
|
149
|
-
return (
|
|
173
|
+
return (
|
|
174
|
+
(freshTokensIn / 1_000_000) * rates.input +
|
|
175
|
+
(cacheReadIn / 1_000_000) * rates.input * CACHE_READ_DISCOUNT +
|
|
176
|
+
(tokensOut / 1_000_000) * rates.output
|
|
177
|
+
);
|
|
150
178
|
}
|
package/src/adapters/types.ts
CHANGED
|
@@ -32,11 +32,21 @@ export interface AdapterInput {
|
|
|
32
32
|
export interface AdapterOutput {
|
|
33
33
|
/** The model's text response. */
|
|
34
34
|
content: string;
|
|
35
|
-
/** Input token count (prompt). */
|
|
35
|
+
/** Input token count (prompt). Total — includes any cached portion. */
|
|
36
36
|
tokensIn: number;
|
|
37
|
+
/**
|
|
38
|
+
* Subset of `tokensIn` that was served from the provider's prompt cache
|
|
39
|
+
* (cheaper). Anthropic returns `cache_read_input_tokens`. OpenAI returns
|
|
40
|
+
* `prompt_tokens_details.cached_tokens`. Adapters that don't support
|
|
41
|
+
* caching yet (or for which caching didn't trigger this run) leave this
|
|
42
|
+
* at 0 — meaning every input token was a fresh hit at full price.
|
|
43
|
+
*/
|
|
44
|
+
cachedTokensIn?: number;
|
|
37
45
|
/** Output token count (completion). */
|
|
38
46
|
tokensOut: number;
|
|
39
|
-
/** Estimated USD cost based on the model's published rates
|
|
47
|
+
/** Estimated USD cost based on the model's published rates, with cache
|
|
48
|
+
* discount applied to `cachedTokensIn` per provider's published rate
|
|
49
|
+
* (Anthropic: 90% off on cache reads; OpenAI: 50% off; Gemini: varies). */
|
|
40
50
|
costUsd: number;
|
|
41
51
|
/** Wall-clock latency in milliseconds. */
|
|
42
52
|
latencyMs: number;
|
|
@@ -51,6 +61,14 @@ export interface Adapter {
|
|
|
51
61
|
readonly name: string;
|
|
52
62
|
/** Underlying provider family (e.g. "openai", "anthropic", "mock"). */
|
|
53
63
|
readonly provider: string;
|
|
64
|
+
/**
|
|
65
|
+
* The model this adapter will call by default, exposed so the
|
|
66
|
+
* orchestrator can pass it to `BudgetTracker.preflightCheck` instead of
|
|
67
|
+
* the previous hardcoded "gpt-4o". (Codex review v0.5 P2 #5.) Adapters
|
|
68
|
+
* with no meaningful default — like Mock — return an opaque string and
|
|
69
|
+
* the budget tracker falls back to its conservative pricing.
|
|
70
|
+
*/
|
|
71
|
+
readonly defaultModel: string;
|
|
54
72
|
/** True if credentials are available and the adapter can be invoked. */
|
|
55
73
|
isAvailable(): Promise<boolean>;
|
|
56
74
|
/** Execute one model call. */
|
package/src/git/status.ts
CHANGED
|
@@ -40,7 +40,7 @@ export async function checkGitStatus(
|
|
|
40
40
|
const normalized = relativePath.replace(/\\/g, "/");
|
|
41
41
|
|
|
42
42
|
try {
|
|
43
|
-
const { stdout } = await execa(
|
|
43
|
+
const { stdout, stderr, exitCode } = await execa(
|
|
44
44
|
"git",
|
|
45
45
|
["status", "--short", "--", normalized],
|
|
46
46
|
{
|
|
@@ -50,20 +50,36 @@ export async function checkGitStatus(
|
|
|
50
50
|
},
|
|
51
51
|
);
|
|
52
52
|
|
|
53
|
+
// Codex review v0.5 P2 #4: previously we ignored exitCode and treated
|
|
54
|
+
// every empty-stdout result as "clean", which silently includes the
|
|
55
|
+
// case where we're not in a git repo at all. Now we look at exitCode
|
|
56
|
+
// and stderr to distinguish "no changes" (exit 0, stdout empty) from
|
|
57
|
+
// "not a git repo" (exit 128, stderr matches).
|
|
58
|
+
if (exitCode !== 0) {
|
|
59
|
+
const stderrText = (stderr ?? "").toString();
|
|
60
|
+
if (
|
|
61
|
+
stderrText.includes("not a git repository") ||
|
|
62
|
+
stderrText.includes("fatal: not a git repository")
|
|
63
|
+
) {
|
|
64
|
+
return { dirty: false, notInGitRepo: true };
|
|
65
|
+
}
|
|
66
|
+
// Some other git failure (corrupt index, etc.) — treat conservatively
|
|
67
|
+
// as no-protection so the caller can decide. Most callers should
|
|
68
|
+
// refuse writes in this case.
|
|
69
|
+
return { dirty: false, notInGitRepo: true };
|
|
70
|
+
}
|
|
71
|
+
|
|
53
72
|
if (stdout.trim().length === 0) {
|
|
54
73
|
return { dirty: false };
|
|
55
74
|
}
|
|
56
75
|
|
|
57
76
|
return { dirty: true, porcelain: stdout };
|
|
58
77
|
} catch (err) {
|
|
59
|
-
// execa throws if git is missing. Surface as not-in-repo
|
|
60
|
-
// proceed cautiously rather than crash.
|
|
78
|
+
// execa throws if git is missing entirely. Surface as not-in-repo.
|
|
61
79
|
const msg = err instanceof Error ? err.message : String(err);
|
|
62
80
|
if (msg.includes("ENOENT")) {
|
|
63
81
|
return { dirty: false, notInGitRepo: true };
|
|
64
82
|
}
|
|
65
|
-
// "not a git repository" returns non-zero but we used reject:false above,
|
|
66
|
-
// so this branch is rare. Still, treat unknown errors as no-protection.
|
|
67
83
|
return { dirty: false, notInGitRepo: true };
|
|
68
84
|
}
|
|
69
85
|
}
|
package/src/index.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* - budget/ ✅ task #14 BudgetTracker + BudgetExceededError
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
export const VERSION = "0.
|
|
16
|
+
export const VERSION = "0.5.1";
|
|
17
17
|
|
|
18
18
|
// Git safety primitives
|
|
19
19
|
export {
|
|
@@ -113,6 +113,8 @@ export { collectGitDiff, type DiffOptions, type DiffResult } from "./review/diff
|
|
|
113
113
|
export {
|
|
114
114
|
writeHumanReviewFile,
|
|
115
115
|
ReviewFileExistsError,
|
|
116
|
+
reviewFilePathFor,
|
|
117
|
+
preflightReviewFileCollision,
|
|
116
118
|
type WriteReviewFileOptions,
|
|
117
119
|
} from "./review/write.js";
|
|
118
120
|
export {
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter a unified git diff so files matching `.gitignore`,
|
|
3
|
+
* `.almightyignore`, or `config.context.exclude` never reach a provider.
|
|
4
|
+
*
|
|
5
|
+
* This is a stronger promise than redaction. Redaction is defense-in-depth
|
|
6
|
+
* on file *contents*; filtering removes whole files from the payload before
|
|
7
|
+
* the provider ever sees them.
|
|
8
|
+
*
|
|
9
|
+
* Codex review v0.5 flagged that the public docs and templates already
|
|
10
|
+
* promise this behavior — this module makes the implementation match.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { readFile } from "node:fs/promises";
|
|
14
|
+
import { existsSync } from "node:fs";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
// `ignore` is a CJS package; under NodeNext module resolution TypeScript
|
|
17
|
+
// won't synth a default export even with esModuleInterop. The package
|
|
18
|
+
// exports `function ignore(...)` as the module itself, plus
|
|
19
|
+
// `module.exports.default = ignore`. Use a runtime require to access the
|
|
20
|
+
// callable form without fighting the type system.
|
|
21
|
+
import { createRequire } from "node:module";
|
|
22
|
+
import type { Ignore } from "ignore";
|
|
23
|
+
const require = createRequire(import.meta.url);
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-explicit-any
|
|
25
|
+
const ignore = require("ignore") as (options?: Record<string, unknown>) => Ignore;
|
|
26
|
+
|
|
27
|
+
export interface DiffFilterOptions {
|
|
28
|
+
/** Repo root containing .gitignore and .almightyignore. */
|
|
29
|
+
repoRoot: string;
|
|
30
|
+
/** Raw unified diff text from `git diff`. */
|
|
31
|
+
diffText: string;
|
|
32
|
+
/** List of files touched by the diff (typically from collectGitDiff). */
|
|
33
|
+
files: string[];
|
|
34
|
+
/**
|
|
35
|
+
* Additional exclude globs from `config.context.exclude`. Gitignore
|
|
36
|
+
* syntax — see `ignore` package docs. Optional.
|
|
37
|
+
*/
|
|
38
|
+
configExclude?: string[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface DiffFilterResult {
|
|
42
|
+
/** Diff text with ignored files' sections removed. */
|
|
43
|
+
filteredDiff: string;
|
|
44
|
+
/** Files that survived filtering. */
|
|
45
|
+
filesIncluded: string[];
|
|
46
|
+
/** Files that were dropped, with a human-readable reason per file. */
|
|
47
|
+
filesSkipped: { path: string; reason: string }[];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Build an Ignore matcher loaded from `.gitignore`, `.almightyignore`, and
|
|
52
|
+
* any config-level exclude globs. Missing files are silently skipped.
|
|
53
|
+
*
|
|
54
|
+
* Important nuance: `.gitignore` rules normally only apply to UNTRACKED
|
|
55
|
+
* files (tracked files in a diff exist because git is tracking them). For
|
|
56
|
+
* AlmightyGPT's purposes we want the conservative behavior — "if it
|
|
57
|
+
* matches gitignore, don't send it" — because secret-bearing tracked
|
|
58
|
+
* files (someone committed `.env` once) are exactly the case we're
|
|
59
|
+
* protecting against. So we apply both sets equally.
|
|
60
|
+
*/
|
|
61
|
+
async function buildIgnoreMatcher(
|
|
62
|
+
repoRoot: string,
|
|
63
|
+
configExclude: string[],
|
|
64
|
+
): Promise<{
|
|
65
|
+
matcher: Ignore;
|
|
66
|
+
sources: { name: string; loaded: boolean; rules: number }[];
|
|
67
|
+
}> {
|
|
68
|
+
const ig = ignore();
|
|
69
|
+
const sources: { name: string; loaded: boolean; rules: number }[] = [];
|
|
70
|
+
|
|
71
|
+
for (const file of [".gitignore", ".almightyignore"]) {
|
|
72
|
+
const path = join(repoRoot, file);
|
|
73
|
+
if (existsSync(path)) {
|
|
74
|
+
const text = await readFile(path, "utf8");
|
|
75
|
+
const lines = text.split("\n").filter((l) => l.trim() && !l.trim().startsWith("#"));
|
|
76
|
+
ig.add(text);
|
|
77
|
+
sources.push({ name: file, loaded: true, rules: lines.length });
|
|
78
|
+
} else {
|
|
79
|
+
sources.push({ name: file, loaded: false, rules: 0 });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (configExclude.length > 0) {
|
|
84
|
+
ig.add(configExclude.join("\n"));
|
|
85
|
+
sources.push({
|
|
86
|
+
name: "config.context.exclude",
|
|
87
|
+
loaded: true,
|
|
88
|
+
rules: configExclude.length,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return { matcher: ig, sources };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Parse a unified git diff into per-file sections. Each section starts
|
|
97
|
+
* with `diff --git a/<path> b/<path>` and runs until the next such header
|
|
98
|
+
* (or end of input).
|
|
99
|
+
*
|
|
100
|
+
* Returns an array of `{ path, section }` so each file's diff hunks can
|
|
101
|
+
* be filtered independently and then reassembled.
|
|
102
|
+
*/
|
|
103
|
+
function splitDiffByFile(
|
|
104
|
+
diffText: string,
|
|
105
|
+
): { path: string; section: string }[] {
|
|
106
|
+
if (!diffText.trim()) return [];
|
|
107
|
+
|
|
108
|
+
const out: { path: string; section: string }[] = [];
|
|
109
|
+
const lines = diffText.split("\n");
|
|
110
|
+
let current: { path: string; lines: string[] } | null = null;
|
|
111
|
+
|
|
112
|
+
const headerRe = /^diff --git a\/(.+?) b\/(.+?)$/;
|
|
113
|
+
|
|
114
|
+
for (const line of lines) {
|
|
115
|
+
const match = line.match(headerRe);
|
|
116
|
+
if (match) {
|
|
117
|
+
if (current) {
|
|
118
|
+
out.push({ path: current.path, section: current.lines.join("\n") });
|
|
119
|
+
}
|
|
120
|
+
// Prefer the "b/" path (post-image) since renames change it.
|
|
121
|
+
// For most diffs both paths match.
|
|
122
|
+
current = { path: match[2]!, lines: [line] };
|
|
123
|
+
} else if (current) {
|
|
124
|
+
current.lines.push(line);
|
|
125
|
+
}
|
|
126
|
+
// Lines before any header (rare; usually empty diff) are dropped.
|
|
127
|
+
}
|
|
128
|
+
if (current) {
|
|
129
|
+
out.push({ path: current.path, section: current.lines.join("\n") });
|
|
130
|
+
}
|
|
131
|
+
return out;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export async function filterDiffByIgnoreLists(
|
|
135
|
+
opts: DiffFilterOptions,
|
|
136
|
+
): Promise<DiffFilterResult> {
|
|
137
|
+
const configExclude = opts.configExclude ?? [];
|
|
138
|
+
const { matcher } = await buildIgnoreMatcher(opts.repoRoot, configExclude);
|
|
139
|
+
|
|
140
|
+
// Parse the diff into per-file sections. If the diff is empty or has no
|
|
141
|
+
// file headers, nothing to filter — return as-is.
|
|
142
|
+
const sections = splitDiffByFile(opts.diffText);
|
|
143
|
+
|
|
144
|
+
if (sections.length === 0) {
|
|
145
|
+
return {
|
|
146
|
+
filteredDiff: opts.diffText,
|
|
147
|
+
filesIncluded: opts.files,
|
|
148
|
+
filesSkipped: [],
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const includedSections: string[] = [];
|
|
153
|
+
const filesIncluded: string[] = [];
|
|
154
|
+
const filesSkipped: { path: string; reason: string }[] = [];
|
|
155
|
+
|
|
156
|
+
for (const { path, section } of sections) {
|
|
157
|
+
if (matcher.ignores(path)) {
|
|
158
|
+
filesSkipped.push({
|
|
159
|
+
path,
|
|
160
|
+
reason: "ignored by .almightyignore / .gitignore / config.context.exclude",
|
|
161
|
+
});
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
includedSections.push(section);
|
|
165
|
+
filesIncluded.push(path);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Also reconcile the original `files` list: any path from collectGitDiff
|
|
169
|
+
// that isn't in the surviving sections is also skipped. Usually they
|
|
170
|
+
// match (collectGitDiff and splitDiffByFile use the same source) but
|
|
171
|
+
// they can diverge if collectGitDiff includes paths that have no diff
|
|
172
|
+
// hunks (e.g. permission-only changes).
|
|
173
|
+
const includedSet = new Set(filesIncluded);
|
|
174
|
+
for (const original of opts.files) {
|
|
175
|
+
if (!includedSet.has(original) && matcher.ignores(original)) {
|
|
176
|
+
if (!filesSkipped.some((s) => s.path === original)) {
|
|
177
|
+
filesSkipped.push({
|
|
178
|
+
path: original,
|
|
179
|
+
reason: "ignored by .almightyignore / .gitignore / config.context.exclude",
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
filteredDiff: includedSections.join("\n"),
|
|
187
|
+
filesIncluded,
|
|
188
|
+
filesSkipped,
|
|
189
|
+
};
|
|
190
|
+
}
|
package/src/review/events.ts
CHANGED
|
@@ -45,6 +45,8 @@ export interface AgentCompletedEvent {
|
|
|
45
45
|
model: string;
|
|
46
46
|
outputPath: string;
|
|
47
47
|
tokensIn: number;
|
|
48
|
+
/** Cache-hit portion of tokensIn (Anthropic cache_read / OpenAI cached). */
|
|
49
|
+
cachedTokensIn?: number;
|
|
48
50
|
tokensOut: number;
|
|
49
51
|
costUsd: number;
|
|
50
52
|
latencyMs: number;
|