@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.
@@ -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
+ };
@@ -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.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
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
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.