@agent-builder-lab/eve-kit 0.0.0-stage → 0.2.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/dist/authorization.d.ts +78 -0
- package/dist/authorization.js +22 -0
- package/dist/channel.d.ts +39 -0
- package/dist/channel.js +86 -0
- package/dist/chunk-3IQOFBSQ.js +82 -0
- package/dist/chunk-LQIDQBNW.js +80 -0
- package/dist/index.d.ts +128 -0
- package/dist/index.js +238 -0
- package/dist/mcp.d.ts +87 -0
- package/dist/mcp.js +277 -0
- package/dist/rate-limit.d.ts +46 -0
- package/dist/rate-limit.js +61 -0
- package/dist/replay.d.ts +36 -0
- package/dist/replay.js +50 -0
- package/package.json +54 -3
- package/README.md +0 -3
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import {
|
|
2
|
+
labAccountOf
|
|
3
|
+
} from "./chunk-LQIDQBNW.js";
|
|
4
|
+
|
|
5
|
+
// src/rate-limit.ts
|
|
6
|
+
function criarLimitePorPessoa(opcoes) {
|
|
7
|
+
const agora = opcoes.agora ?? Date.now;
|
|
8
|
+
const porChave = /* @__PURE__ */ new Map();
|
|
9
|
+
function contar(chave, regra, t) {
|
|
10
|
+
const janela = porChave.get(chave) ?? { marcas: [] };
|
|
11
|
+
janela.marcas = janela.marcas.filter((m) => t - m < regra.janelaMs);
|
|
12
|
+
porChave.set(chave, janela);
|
|
13
|
+
return janela.marcas.length >= regra.max;
|
|
14
|
+
}
|
|
15
|
+
function registrar(chaves, t) {
|
|
16
|
+
for (const chave of chaves) {
|
|
17
|
+
const janela = porChave.get(chave) ?? { marcas: [] };
|
|
18
|
+
janela.marcas.push(t);
|
|
19
|
+
porChave.set(chave, janela);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return (ctx) => {
|
|
23
|
+
const conta = labAccountOf(ctx);
|
|
24
|
+
const pessoa = conta ? conta.id : `sessao:${ctx.session.id}`;
|
|
25
|
+
const nome = conta?.name ?? "voc\xEA";
|
|
26
|
+
const t = agora();
|
|
27
|
+
const chavePessoa = `p:${pessoa}:${ctx.toolName}`;
|
|
28
|
+
if (contar(chavePessoa, opcoes.porPessoa, t)) {
|
|
29
|
+
return {
|
|
30
|
+
type: "denied",
|
|
31
|
+
reason: `Limite de uso: ${nome} j\xE1 usou ${ctx.toolName} ${opcoes.porPessoa.max} vez(es) no per\xEDodo. Tente de novo mais tarde.`
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const chaves = [chavePessoa];
|
|
35
|
+
if (opcoes.porFerramenta) {
|
|
36
|
+
const chaveFerramenta = `f:${ctx.toolName}`;
|
|
37
|
+
if (contar(chaveFerramenta, opcoes.porFerramenta, t)) {
|
|
38
|
+
return {
|
|
39
|
+
type: "denied",
|
|
40
|
+
reason: `Limite de uso: ${ctx.toolName} atingiu o teto de chamadas do time no per\xEDodo.`
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
chaves.push(chaveFerramenta);
|
|
44
|
+
}
|
|
45
|
+
registrar(chaves, t);
|
|
46
|
+
return opcoes.next ? opcoes.next(ctx) : "not-applicable";
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function limitePorCusto(opcoes) {
|
|
50
|
+
return ({ window }) => {
|
|
51
|
+
if (opcoes.maxUsd !== void 0 && (window.costUsd ?? 0) >= opcoes.maxUsd) return true;
|
|
52
|
+
if (opcoes.maxInputTokens !== void 0) {
|
|
53
|
+
if (window.inputTokens - window.cacheReadTokens >= opcoes.maxInputTokens) return true;
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
criarLimitePorPessoa,
|
|
60
|
+
limitePorCusto
|
|
61
|
+
};
|
package/dist/replay.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as eve from 'eve';
|
|
2
|
+
import { AgentStaticModelDefinition, DynamicResolveContext } from 'eve';
|
|
3
|
+
|
|
4
|
+
/** O modelo de verdade: fixo ou escolhido a cada step, como num `defineDynamic`. */
|
|
5
|
+
type LabModelChoice = AgentStaticModelDefinition | {
|
|
6
|
+
model: AgentStaticModelDefinition;
|
|
7
|
+
modelContextWindowTokens?: number;
|
|
8
|
+
reasoning?: "provider-default" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh";
|
|
9
|
+
};
|
|
10
|
+
type LabModelResolver = (event: unknown, ctx: DynamicResolveContext) => LabModelChoice | Promise<LabModelChoice>;
|
|
11
|
+
interface LabReplayOptions {
|
|
12
|
+
/** Porta local do conector. Padrão: `LAB_CONNECTOR_URL` ou http://127.0.0.1:2100. */
|
|
13
|
+
connectorUrl?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Janela informada ao eve nos steps repetidos (o `mockModel` não está no catálogo do AI
|
|
16
|
+
* Gateway, e o eve recusa um modelo dinâmico sem janela). Padrão: 1 milhão de tokens.
|
|
17
|
+
*/
|
|
18
|
+
replayContextWindowTokens?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Modelo do agente com replay para o Agent Builder Lab, para o `model` do `agent.ts`:
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { labReplayModel } from "@agent-builder-lab/eve-kit/replay";
|
|
25
|
+
* export default defineAgent({ model: labReplayModel("anthropic/claude-sonnet-5.5") });
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* Fora de um fork do lab, devolve o seu modelo em todo step. Num fork (o canal do lab marca o
|
|
29
|
+
* turno com o id), repete os steps gravados antes da volta editada, inclusive ela, com um
|
|
30
|
+
* `mockModel`: mesmo texto, mesmas tool calls e mesmos ids. Assim as voltas anteriores saem
|
|
31
|
+
* iguais às originais e o modelo de verdade só entra depois do ponto editado. O `modelId` desses
|
|
32
|
+
* steps é `lab-replay/<modelo original>`.
|
|
33
|
+
*/
|
|
34
|
+
declare function labReplayModel(model: LabModelChoice | LabModelResolver, options?: LabReplayOptions): eve.DynamicSentinel<LabModelChoice>;
|
|
35
|
+
|
|
36
|
+
export { type LabModelChoice, type LabModelResolver, type LabReplayOptions, labReplayModel };
|
package/dist/replay.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LAB_FORK_ATTRIBUTE,
|
|
3
|
+
REPLAY_PROVIDER,
|
|
4
|
+
fetchForkPlan
|
|
5
|
+
} from "./chunk-3IQOFBSQ.js";
|
|
6
|
+
|
|
7
|
+
// src/replay.ts
|
|
8
|
+
import { defineDynamic } from "eve";
|
|
9
|
+
import { mockModel } from "eve/evals";
|
|
10
|
+
function labReplayModel(model, options = {}) {
|
|
11
|
+
const real = (event, ctx) => typeof model === "function" ? model(event, ctx) : model;
|
|
12
|
+
return defineDynamic({
|
|
13
|
+
events: {
|
|
14
|
+
"step.started": async (event, ctx) => {
|
|
15
|
+
const forkId = ctx.session.auth.current?.attributes[LAB_FORK_ATTRIBUTE];
|
|
16
|
+
if (typeof forkId !== "string") return real(event, ctx);
|
|
17
|
+
const plan = await fetchForkPlan(forkId, options.connectorUrl).catch(() => void 0);
|
|
18
|
+
const step = plan?.replay?.steps[stepIndexOf(event)];
|
|
19
|
+
if (!step) return real(event, ctx);
|
|
20
|
+
return {
|
|
21
|
+
model: replayStep(step, plan?.replay?.modelId),
|
|
22
|
+
modelContextWindowTokens: options.replayContextWindowTokens ?? 1e6
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function stepIndexOf(event) {
|
|
29
|
+
const record = event ?? {};
|
|
30
|
+
const index = record.data?.stepIndex ?? record.stepIndex;
|
|
31
|
+
return typeof index === "number" ? index : -1;
|
|
32
|
+
}
|
|
33
|
+
function replayStep(step, modelId = "modelo") {
|
|
34
|
+
return mockModel({
|
|
35
|
+
provider: REPLAY_PROVIDER,
|
|
36
|
+
modelId,
|
|
37
|
+
respond: () => ({
|
|
38
|
+
text: step.text || void 0,
|
|
39
|
+
toolCalls: step.toolCalls.map((call) => ({
|
|
40
|
+
id: call.id,
|
|
41
|
+
name: call.name,
|
|
42
|
+
input: call.input
|
|
43
|
+
})),
|
|
44
|
+
usage: step.usage
|
|
45
|
+
})
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
labReplayModel
|
|
50
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,57 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-builder-lab/eve-kit",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Liga um agente eve ao Agent Builder Lab: instrumentação da janela de contexto, canal com history e stubs, replay e autorização por conta de teste.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"import": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"./authorization": {
|
|
12
|
+
"types": "./dist/authorization.d.ts",
|
|
13
|
+
"import": "./dist/authorization.js"
|
|
14
|
+
},
|
|
15
|
+
"./channel": {
|
|
16
|
+
"types": "./dist/channel.d.ts",
|
|
17
|
+
"import": "./dist/channel.js"
|
|
18
|
+
},
|
|
19
|
+
"./replay": {
|
|
20
|
+
"types": "./dist/replay.d.ts",
|
|
21
|
+
"import": "./dist/replay.js"
|
|
22
|
+
},
|
|
23
|
+
"./mcp": {
|
|
24
|
+
"types": "./dist/mcp.d.ts",
|
|
25
|
+
"import": "./dist/mcp.js"
|
|
26
|
+
},
|
|
27
|
+
"./limits": {
|
|
28
|
+
"types": "./dist/rate-limit.d.ts",
|
|
29
|
+
"import": "./dist/rate-limit.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist"
|
|
34
|
+
],
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=24"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"eve": ">=0.83.0 <0.84.0"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "24.19.2",
|
|
46
|
+
"eve": "0.83.2",
|
|
47
|
+
"tsup": "8.5.1",
|
|
48
|
+
"typescript": "6.0.3",
|
|
49
|
+
"vitest": "5.0.5",
|
|
50
|
+
"@lab/config": "0.0.0"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "tsup",
|
|
54
|
+
"typecheck": "tsc --noEmit",
|
|
55
|
+
"test": "vitest run"
|
|
56
|
+
}
|
|
6
57
|
}
|
package/README.md
DELETED