@opengeni/jev 0.1.0-canary.36199476632001
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/LICENSE +190 -0
- package/README.md +140 -0
- package/dist/circuit-breaker.d.ts +58 -0
- package/dist/client.d.ts +173 -0
- package/dist/code-search/config.d.ts +142 -0
- package/dist/code-search/judge.d.ts +169 -0
- package/dist/code-search/leads.d.ts +96 -0
- package/dist/code-search/pack.d.ts +106 -0
- package/dist/code-search/recall.d.ts +155 -0
- package/dist/code-search/search.d.ts +93 -0
- package/dist/code-search/session.d.ts +33 -0
- package/dist/code-search/text.d.ts +35 -0
- package/dist/code-search/tool.d.ts +34 -0
- package/dist/code-search/windows.d.ts +85 -0
- package/dist/code-search/workspace.d.ts +51 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +3110 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
- package/src/circuit-breaker.ts +135 -0
- package/src/client.ts +577 -0
- package/src/code-search/config.ts +282 -0
- package/src/code-search/judge.ts +413 -0
- package/src/code-search/leads.ts +442 -0
- package/src/code-search/pack.ts +354 -0
- package/src/code-search/recall.ts +648 -0
- package/src/code-search/search.ts +773 -0
- package/src/code-search/session.ts +89 -0
- package/src/code-search/text.ts +159 -0
- package/src/code-search/tool.ts +209 -0
- package/src/code-search/windows.ts +617 -0
- package/src/code-search/workspace.ts +55 -0
- package/src/index.ts +71 -0
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@opengeni/jev",
|
|
3
|
+
"version": "0.1.0-canary.36199476632001",
|
|
4
|
+
"description": "TypeSafe Jev client and the Jev-ranked code_search engine behind the worker's code_search agent tool.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/Cloudgeni-ai/opengeni.git",
|
|
9
|
+
"directory": "packages/jev"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"src",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"type": "module",
|
|
17
|
+
"sideEffects": false,
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"module": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public",
|
|
29
|
+
"provenance": true
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "bun ../../scripts/build-typescript-package.ts",
|
|
33
|
+
"typecheck": "tsc --noEmit",
|
|
34
|
+
"prepublishOnly": "bash ../../scripts/prepublish-guard"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-process circuit breaker for Jev. Consecutive JevUnavailableError failures open it for a cooldown, so a
|
|
3
|
+
* Jev outage costs one fast refusal per call instead of a full retry cycle. After the cooldown the breaker is
|
|
4
|
+
* half-open and tryAcquire() admits exactly one trial call at a time.
|
|
5
|
+
*
|
|
6
|
+
* Every admitted call gets a lease and settles it exactly once:
|
|
7
|
+
* - recordSuccess(lease) from any call closes the breaker, because any success proves Jev works.
|
|
8
|
+
* - recordFailure(unavailable, now, lease) from any call counts, and reopens a half-open breaker at once.
|
|
9
|
+
* - release(lease) (the call never reached Jev) or recordFailure with another error (a rejected request, a
|
|
10
|
+
* workspace failure, an abort) neither counts nor resets the streak. It ends the trial only when that
|
|
11
|
+
* lease is the trial, so a call admitted while closed cannot free the slot of a trial running now.
|
|
12
|
+
* isOpen() and status() are for metrics and diagnostics. Do not use them to decide which tools a turn is
|
|
13
|
+
* offered: that list is part of the model's cached prompt prefix and must not change with transient health.
|
|
14
|
+
* The worker keeps one breaker per process.
|
|
15
|
+
*/
|
|
16
|
+
import { JevUnavailableError } from "./client";
|
|
17
|
+
|
|
18
|
+
export interface JevCircuitBreakerOptions {
|
|
19
|
+
/** Consecutive unavailable failures that open the breaker. */
|
|
20
|
+
failureThreshold?: number | undefined;
|
|
21
|
+
/** Cooldown after an outage-style failure. */
|
|
22
|
+
cooldownMs?: number | undefined;
|
|
23
|
+
/** Cooldown when the opening failure was HTTP 401/402/403 (key or billing problem). */
|
|
24
|
+
authCooldownMs?: number | undefined;
|
|
25
|
+
/** A half-open trial that has not ended after this long no longer blocks the next trial. */
|
|
26
|
+
trialTimeoutMs?: number | undefined;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** One admitted call. Leases are matched by identity, so only the issued object ends its trial. */
|
|
30
|
+
export interface JevCircuitLease {
|
|
31
|
+
readonly id: number;
|
|
32
|
+
/** This call is the half-open trial. */
|
|
33
|
+
readonly trial: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type JevCircuitState = "closed" | "open" | "half_open";
|
|
37
|
+
|
|
38
|
+
export interface JevCircuitStatus {
|
|
39
|
+
state: JevCircuitState;
|
|
40
|
+
consecutiveFailures: number;
|
|
41
|
+
/** Epoch ms until which calls are refused; null when not open. */
|
|
42
|
+
openUntil: number | null;
|
|
43
|
+
/** Half-open and the one trial call is running. */
|
|
44
|
+
trialInFlight: boolean;
|
|
45
|
+
lastFailure: { message: string; status: number | null; at: number } | null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export class JevCircuitBreaker {
|
|
49
|
+
private readonly failureThreshold: number;
|
|
50
|
+
private readonly cooldownMs: number;
|
|
51
|
+
private readonly authCooldownMs: number;
|
|
52
|
+
private readonly trialTimeoutMs: number;
|
|
53
|
+
private consecutiveFailures = 0;
|
|
54
|
+
private openUntil: number | null = null;
|
|
55
|
+
private trial: { lease: JevCircuitLease; startedAt: number } | null = null;
|
|
56
|
+
private nextLeaseId = 1;
|
|
57
|
+
private lastFailure: JevCircuitStatus["lastFailure"] = null;
|
|
58
|
+
|
|
59
|
+
constructor(options: JevCircuitBreakerOptions = {}) {
|
|
60
|
+
this.failureThreshold = Math.max(1, options.failureThreshold ?? 3);
|
|
61
|
+
this.cooldownMs = options.cooldownMs ?? 5 * 60_000;
|
|
62
|
+
this.authCooldownMs = options.authCooldownMs ?? 30 * 60_000;
|
|
63
|
+
// Longer than one Jev retry cycle at the largest allowed request timeout (3 attempts of up to
|
|
64
|
+
// 120 s, OPENGENI_JEV_REQUEST_TIMEOUT_MS) plus backoff and sandbox recall, so a slow trial is not
|
|
65
|
+
// mistaken for a stuck one and joined by a second trial.
|
|
66
|
+
this.trialTimeoutMs = options.trialTimeoutMs ?? 10 * 60_000;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** True while calls should be refused without contacting Jev (the cooldown is running). */
|
|
70
|
+
isOpen(now: number = Date.now()): boolean {
|
|
71
|
+
return this.openUntil !== null && now < this.openUntil;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Admit one call and return its lease, or null when refused. Closed: always. Open: never. Half-open:
|
|
76
|
+
* only the first caller, as the trial, until its lease is settled or it has run for trialTimeoutMs, so
|
|
77
|
+
* a trial that never ends cannot block the tool for good.
|
|
78
|
+
*/
|
|
79
|
+
tryAcquire(now: number = Date.now()): JevCircuitLease | null {
|
|
80
|
+
if (this.openUntil === null) return this.issue(false);
|
|
81
|
+
if (now < this.openUntil) return null;
|
|
82
|
+
if (this.trial !== null && now - this.trial.startedAt < this.trialTimeoutMs) return null;
|
|
83
|
+
const lease = this.issue(true);
|
|
84
|
+
this.trial = { lease, startedAt: now };
|
|
85
|
+
return lease;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** End an admitted call that did not contact Jev, so its outcome says nothing about Jev. */
|
|
89
|
+
release(lease: JevCircuitLease): void {
|
|
90
|
+
if (this.trial !== null && this.trial.lease === lease) this.trial = null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Any call's success proves Jev works, so the lease does not change the outcome. */
|
|
94
|
+
recordSuccess(_lease?: JevCircuitLease | null): void {
|
|
95
|
+
this.consecutiveFailures = 0;
|
|
96
|
+
this.openUntil = null;
|
|
97
|
+
this.trial = null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Settle a failed call. A failure without a lease counts the same but never ends a trial. */
|
|
101
|
+
recordFailure(error: unknown, now: number = Date.now(), lease?: JevCircuitLease | null): void {
|
|
102
|
+
if (!(error instanceof JevUnavailableError)) {
|
|
103
|
+
if (lease) this.release(lease);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const halfOpen = this.openUntil !== null && now >= this.openUntil;
|
|
107
|
+
this.consecutiveFailures += 1;
|
|
108
|
+
this.lastFailure = { message: error.message, status: error.status ?? null, at: now };
|
|
109
|
+
if (halfOpen || this.consecutiveFailures >= this.failureThreshold) {
|
|
110
|
+
const auth = error.status === 401 || error.status === 402 || error.status === 403;
|
|
111
|
+
this.openUntil = now + (auth ? this.authCooldownMs : this.cooldownMs);
|
|
112
|
+
// A new cooldown starts: whatever trial was running no longer blocks the next one.
|
|
113
|
+
this.trial = null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
status(now: number = Date.now()): JevCircuitStatus {
|
|
118
|
+
const state: JevCircuitState =
|
|
119
|
+
this.openUntil === null ? "closed" : now < this.openUntil ? "open" : "half_open";
|
|
120
|
+
return {
|
|
121
|
+
state,
|
|
122
|
+
consecutiveFailures: this.consecutiveFailures,
|
|
123
|
+
openUntil: state === "open" ? this.openUntil : null,
|
|
124
|
+
trialInFlight:
|
|
125
|
+
state === "half_open" &&
|
|
126
|
+
this.trial !== null &&
|
|
127
|
+
now - this.trial.startedAt < this.trialTimeoutMs,
|
|
128
|
+
lastFailure: this.lastFailure,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private issue(trial: boolean): JevCircuitLease {
|
|
133
|
+
return Object.freeze({ id: this.nextLeaseId++, trial });
|
|
134
|
+
}
|
|
135
|
+
}
|