prova-agent-kit 0.1.0 → 0.1.2
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 +4 -2
- package/dist/adapter.js +4 -1
- package/dist/adapter.js.map +1 -1
- package/dist/attach.js +11 -8
- package/dist/attach.js.map +1 -1
- package/dist/batcher.d.ts +2 -2
- package/dist/batcher.d.ts.map +1 -1
- package/dist/batcher.js +34 -17
- package/dist/batcher.js.map +1 -1
- package/dist/index.js +15 -5
- package/dist/index.js.map +1 -1
- package/dist/payload.js +8 -3
- package/dist/payload.js.map +1 -1
- package/dist/runtime.d.ts +3 -3
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +11 -6
- package/dist/runtime.js.map +1 -1
- package/dist/types.d.ts +7 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -1
- package/dist/types.js.map +1 -1
- package/dist/wallet.js +7 -3
- package/dist/wallet.js.map +1 -1
- package/package.json +1 -1
- package/src/attach.test.ts +2 -2
- package/src/batcher.test.ts +70 -0
- package/src/batcher.ts +32 -17
- package/src/runtime.ts +7 -7
- package/src/types.ts +7 -3
package/README.md
CHANGED
|
@@ -50,17 +50,19 @@ const agent = new SolanaAgentKit(new ProvaWallet(realWallet, { attester }), RPC_
|
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
### No bloquea al agente
|
|
53
|
-
Las atestaciones son **fire-and-forget con batching**: un fallo de Prova nunca rompe ni frena una acción del agente.
|
|
53
|
+
Las atestaciones son **fire-and-forget con batching por debounce**: un fallo de Prova nunca rompe ni frena una acción del agente. Una ráfaga de tool calls (multi-tool-calling) se agrupa y se envía en **UNA sola tx** (`batchAttest`, hasta 100) apenas la ráfaga se detiene (`flushDelayMs`), o al llegar a `maxSize`.
|
|
54
54
|
|
|
55
55
|
```typescript
|
|
56
56
|
attachProva(agent, {
|
|
57
57
|
attester,
|
|
58
58
|
rules: (name) => name !== 'fetchPrice', // qué acciones atestar (default: todas)
|
|
59
|
-
batch: { maxSize: 25,
|
|
59
|
+
batch: { maxSize: 25, flushDelayMs: 1000 }, // agrupa la ráfaga y envía ~1s tras la última acción
|
|
60
60
|
onError: (err, ctx) => logger.warn(ctx.action, err),
|
|
61
61
|
});
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
> **Importante:** llama a `handle.stop()` cuando el agente termine su turno para garantizar el flush final de lo pendiente.
|
|
65
|
+
|
|
64
66
|
## Modelo de claves
|
|
65
67
|
Prova atesta con **su propio par operador/agente de Devnet**, independiente del wallet de trading del agente. Ventajas: no necesita la private key de trading, funciona con wallets Privy/Turnkey, y el operador Prova es la identidad que avala al agente. Registra el agente una vez con `prova.registerAgent({ operatorKeypair })`.
|
|
66
68
|
|
package/dist/adapter.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
// Puente entre el `ProvaClient` real (prova-agent-sdk) y la interfaz
|
|
2
3
|
// `ProvaAttester` que usa el adapter. Tipado estructural → no importamos el SDK.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.attesterFromProvaClient = attesterFromProvaClient;
|
|
3
6
|
/**
|
|
4
7
|
* Construye un `ProvaAttester` a partir de un `ProvaClient` real, la función
|
|
5
8
|
* estática `ProvaClient.hashAction` y la keypair operadora de Prova.
|
|
@@ -7,7 +10,7 @@
|
|
|
7
10
|
* @example
|
|
8
11
|
* const attester = attesterFromProvaClient(prova, ProvaClient.hashAction, operatorKeypair);
|
|
9
12
|
*/
|
|
10
|
-
|
|
13
|
+
function attesterFromProvaClient(client, hashAction, operatorKeypair) {
|
|
11
14
|
return {
|
|
12
15
|
hashAction,
|
|
13
16
|
attest: (item) => client.attest({
|
package/dist/adapter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,iFAAiF;
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":";AAAA,qEAAqE;AACrE,iFAAiF;;AAwBjF,0DAgBC;AAvBD;;;;;;GAMG;AACH,SAAgB,uBAAuB,CACrC,MAAuB,EACvB,UAAoD,EACpD,eAAwB;IAExB,OAAO;QACL,UAAU;QACV,MAAM,EAAE,CAAC,IAAqB,EAAE,EAAE,CAChC,MAAM,CAAC,MAAM,CAAC;YACZ,eAAe;YACf,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC;QACJ,WAAW,EAAE,CAAC,KAAwB,EAAE,EAAE,CACxC,MAAM,CAAC,WAAW,CAAC,EAAE,eAAe,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;KAC/D,CAAC;AACJ,CAAC"}
|
package/dist/attach.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
// Enfoque B: envuelve los handlers de las acciones del agente para atestar cada
|
|
2
3
|
// ejecución en Prova. Es el mecanismo principal de captura (semántica rica:
|
|
3
4
|
// nombre + input + output). Llamar DESPUÉS de registrar todos los plugins.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.attachProva = attachProva;
|
|
7
|
+
const payload_1 = require("./payload");
|
|
8
|
+
const batcher_1 = require("./batcher");
|
|
9
|
+
const runtime_1 = require("./runtime");
|
|
10
|
+
function attachProva(agent, options) {
|
|
8
11
|
const { attester } = options;
|
|
9
12
|
const should = options.rules ?? (() => true);
|
|
10
13
|
const onError = options.onError ??
|
|
11
|
-
((error, context) => warn(`[Prova] attest failed for "${context.action}":`, error));
|
|
12
|
-
const batcher = createBatcher(attester, options.batch, (error) => onError(error, { action: 'batch' }));
|
|
14
|
+
((error, context) => (0, runtime_1.warn)(`[Prova] attest failed for "${context.action}":`, error));
|
|
15
|
+
const batcher = (0, batcher_1.createBatcher)(attester, options.batch, (error) => onError(error, { action: 'batch' }));
|
|
13
16
|
agent.actions = agent.actions.map((action) => {
|
|
14
17
|
if (!should(action.name))
|
|
15
18
|
return action;
|
|
@@ -30,8 +33,8 @@ export function attachProva(agent, options) {
|
|
|
30
33
|
};
|
|
31
34
|
}
|
|
32
35
|
async function captureAction(attester, batcher, name, input, result) {
|
|
33
|
-
const payload = buildPayload(name, input, result);
|
|
36
|
+
const payload = (0, payload_1.buildPayload)(name, input, result);
|
|
34
37
|
const actionHash = await attester.hashAction(JSON.stringify(payload));
|
|
35
|
-
batcher.add({ actionHash, actionType: mapActionType(name, result) });
|
|
38
|
+
batcher.add({ actionHash, actionType: (0, payload_1.mapActionType)(name, result) });
|
|
36
39
|
}
|
|
37
40
|
//# sourceMappingURL=attach.js.map
|
package/dist/attach.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attach.js","sourceRoot":"","sources":["../src/attach.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,4EAA4E;AAC5E,2EAA2E;
|
|
1
|
+
{"version":3,"file":"attach.js","sourceRoot":"","sources":["../src/attach.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,4EAA4E;AAC5E,2EAA2E;;AAc3E,kCAgCC;AA3CD,uCAAwD;AACxD,uCAAwD;AACxD,uCAAiC;AASjC,SAAgB,WAAW,CAAC,KAAgB,EAAE,OAA2B;IACvE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,OAAO,GACX,OAAO,CAAC,OAAO;QACf,CAAC,CAAC,KAAc,EAAE,OAA2B,EAAE,EAAE,CAC/C,IAAA,cAAI,EAAC,8BAA8B,OAAO,CAAC,MAAM,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IAEnE,MAAM,OAAO,GAAG,IAAA,uBAAa,EAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAC/D,OAAO,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CACpC,CAAC;IAEF,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAkB,EAAc,EAAE;QACnE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,OAAO,MAAM,CAAC;QACxC,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC;QAChC,OAAO;YACL,GAAG,MAAM;YACT,OAAO,EAAE,KAAK,EAAE,CAAU,EAAE,KAA8B,EAAE,EAAE;gBAC5D,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;gBACxC,qEAAqE;gBACrE,KAAK,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAChF,OAAO,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CACxC,CAAC;gBACF,OAAO,MAAM,CAAC;YAChB,CAAC;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE;QAC5B,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE;KAC3B,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,QAAuB,EACvB,OAAgB,EAChB,IAAY,EACZ,KAA8B,EAC9B,MAA+B;IAE/B,MAAM,OAAO,GAAG,IAAA,sBAAY,EAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,IAAA,uBAAa,EAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AACvE,CAAC"}
|
package/dist/batcher.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { AttestationItem, BatchOptions, ProvaAttester } from './types';
|
|
2
2
|
export interface Batcher {
|
|
3
|
-
/** Encola una atestación;
|
|
3
|
+
/** Encola una atestación; programa el flush (o lo dispara si se alcanza maxSize). */
|
|
4
4
|
add(item: AttestationItem): void;
|
|
5
5
|
/** Envía inmediatamente lo pendiente. */
|
|
6
6
|
flush(): Promise<void>;
|
|
7
|
-
/**
|
|
7
|
+
/** Cancela el timer y hace un último flush (llamar al cerrar el agente). */
|
|
8
8
|
stop(): Promise<void>;
|
|
9
9
|
}
|
|
10
10
|
export declare function createBatcher(attester: ProvaAttester, options?: BatchOptions, onError?: (error: unknown) => void): Batcher;
|
package/dist/batcher.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batcher.d.ts","sourceRoot":"","sources":["../src/batcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"batcher.d.ts","sourceRoot":"","sources":["../src/batcher.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG5E,MAAM,WAAW,OAAO;IACtB,qFAAqF;IACrF,GAAG,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,yCAAyC;IACzC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,4EAA4E;IAC5E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAMD,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,aAAa,EACvB,OAAO,GAAE,YAAiB,EAC1B,OAAO,GAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAqD,GACjF,OAAO,CAwDT"}
|
package/dist/batcher.js
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
// Buffer de atestaciones con flush por DEBOUNCE: agrupa una ráfaga de acciones
|
|
3
|
+
// (multi-tool-calling) y las envía en UNA sola tx (batchAttest, hasta 100) apenas
|
|
4
|
+
// la ráfaga se detiene. Esto arregla el bug de "N tool calls seguidos → 0 guardadas":
|
|
5
|
+
// antes el flush solo ocurría a los 25 items o cada 10s, así que una ráfaga corta
|
|
6
|
+
// que terminaba antes quedaba sin enviar.
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.createBatcher = createBatcher;
|
|
9
|
+
const runtime_1 = require("./runtime");
|
|
5
10
|
const DEFAULT_MAX_SIZE = 25;
|
|
6
|
-
const
|
|
11
|
+
const DEFAULT_FLUSH_DELAY_MS = 1000;
|
|
7
12
|
const HARD_BATCH_LIMIT = 100;
|
|
8
|
-
|
|
13
|
+
function createBatcher(attester, options = {}, onError = (error) => (0, runtime_1.warn)('[Prova] batch error:', error)) {
|
|
9
14
|
const maxSize = Math.min(Math.max(options.maxSize ?? DEFAULT_MAX_SIZE, 1), HARD_BATCH_LIMIT);
|
|
10
|
-
const
|
|
15
|
+
const flushDelayMs = options.flushDelayMs ?? DEFAULT_FLUSH_DELAY_MS;
|
|
11
16
|
let buffer = [];
|
|
12
17
|
let timer;
|
|
18
|
+
function clearTimer() {
|
|
19
|
+
if (timer !== undefined) {
|
|
20
|
+
(0, runtime_1.clearTimeoutSafe)(timer);
|
|
21
|
+
timer = undefined;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
13
24
|
async function flush() {
|
|
25
|
+
clearTimer();
|
|
14
26
|
if (buffer.length === 0)
|
|
15
27
|
return;
|
|
16
28
|
const batch = buffer;
|
|
@@ -27,24 +39,29 @@ export function createBatcher(attester, options = {}, onError = (error) => warn(
|
|
|
27
39
|
onError(error);
|
|
28
40
|
}
|
|
29
41
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
42
|
+
// Debounce: cada acción reinicia el timer, de modo que el flush ocurre
|
|
43
|
+
// `flushDelayMs` ms DESPUÉS de la última acción de la ráfaga → todo en 1 tx.
|
|
44
|
+
function scheduleFlush() {
|
|
45
|
+
clearTimer();
|
|
46
|
+
if (flushDelayMs <= 0) {
|
|
47
|
+
void flush();
|
|
48
|
+
return;
|
|
33
49
|
}
|
|
50
|
+
timer = (0, runtime_1.setTimeoutSafe)(() => void flush(), flushDelayMs);
|
|
34
51
|
}
|
|
35
52
|
return {
|
|
36
53
|
add(item) {
|
|
37
54
|
buffer.push(item);
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
55
|
+
if (buffer.length >= maxSize) {
|
|
56
|
+
void flush(); // llegó al tope → envía ya
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
scheduleFlush(); // si no, agrupa la ráfaga y envía al detenerse
|
|
60
|
+
}
|
|
41
61
|
},
|
|
42
62
|
flush,
|
|
43
63
|
async stop() {
|
|
44
|
-
|
|
45
|
-
clearIntervalSafe(timer);
|
|
46
|
-
timer = undefined;
|
|
47
|
-
}
|
|
64
|
+
clearTimer();
|
|
48
65
|
await flush();
|
|
49
66
|
},
|
|
50
67
|
};
|
package/dist/batcher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batcher.js","sourceRoot":"","sources":["../src/batcher.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,
|
|
1
|
+
{"version":3,"file":"batcher.js","sourceRoot":"","sources":["../src/batcher.ts"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,kFAAkF;AAClF,sFAAsF;AACtF,kFAAkF;AAClF,0CAA0C;;AAkB1C,sCA4DC;AA3ED,uCAAiF;AAWjF,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAC5B,MAAM,sBAAsB,GAAG,IAAI,CAAC;AACpC,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B,SAAgB,aAAa,CAC3B,QAAuB,EACvB,UAAwB,EAAE,EAC1B,UAAoC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAA,cAAI,EAAC,sBAAsB,EAAE,KAAK,CAAC;IAElF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,gBAAgB,EAAE,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAC7F,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,sBAAsB,CAAC;IAEpE,IAAI,MAAM,GAAsB,EAAE,CAAC;IACnC,IAAI,KAA0B,CAAC;IAE/B,SAAS,UAAU;QACjB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,IAAA,0BAAgB,EAAC,KAAK,CAAC,CAAC;YACxB,KAAK,GAAG,SAAS,CAAC;QACpB,CAAC;IACH,CAAC;IAED,KAAK,UAAU,KAAK;QAClB,UAAU,EAAE,CAAC;QACb,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAChC,MAAM,KAAK,GAAG,MAAM,CAAC;QACrB,MAAM,GAAG,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,MAAM,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACN,MAAM,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,6EAA6E;IAC7E,SAAS,aAAa;QACpB,UAAU,EAAE,CAAC;QACb,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;YACtB,KAAK,KAAK,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QACD,KAAK,GAAG,IAAA,wBAAc,EAAC,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE,EAAE,YAAY,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO;QACL,GAAG,CAAC,IAAqB;YACvB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClB,IAAI,MAAM,CAAC,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,KAAK,KAAK,EAAE,CAAC,CAAC,2BAA2B;YAC3C,CAAC;iBAAM,CAAC;gBACN,aAAa,EAAE,CAAC,CAAC,+CAA+C;YAClE,CAAC;QACH,CAAC;QACD,KAAK;QACL,KAAK,CAAC,IAAI;YACR,UAAU,EAAE,CAAC;YACb,MAAM,KAAK,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
// API pública del adapter Prova ↔ Solana Agent Kit.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.extractSignature = exports.mapActionType = exports.buildPayload = exports.createBatcher = exports.attesterFromProvaClient = exports.ProvaWallet = exports.attachProva = void 0;
|
|
5
|
+
var attach_1 = require("./attach");
|
|
6
|
+
Object.defineProperty(exports, "attachProva", { enumerable: true, get: function () { return attach_1.attachProva; } });
|
|
7
|
+
var wallet_1 = require("./wallet");
|
|
8
|
+
Object.defineProperty(exports, "ProvaWallet", { enumerable: true, get: function () { return wallet_1.ProvaWallet; } });
|
|
9
|
+
var adapter_1 = require("./adapter");
|
|
10
|
+
Object.defineProperty(exports, "attesterFromProvaClient", { enumerable: true, get: function () { return adapter_1.attesterFromProvaClient; } });
|
|
11
|
+
var batcher_1 = require("./batcher");
|
|
12
|
+
Object.defineProperty(exports, "createBatcher", { enumerable: true, get: function () { return batcher_1.createBatcher; } });
|
|
13
|
+
var payload_1 = require("./payload");
|
|
14
|
+
Object.defineProperty(exports, "buildPayload", { enumerable: true, get: function () { return payload_1.buildPayload; } });
|
|
15
|
+
Object.defineProperty(exports, "mapActionType", { enumerable: true, get: function () { return payload_1.mapActionType; } });
|
|
16
|
+
Object.defineProperty(exports, "extractSignature", { enumerable: true, get: function () { return payload_1.extractSignature; } });
|
|
7
17
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oDAAoD
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,oDAAoD;;;AAEpD,mCAAuC;AAA9B,qGAAA,WAAW,OAAA;AAGpB,mCAAuC;AAA9B,qGAAA,WAAW,OAAA;AAGpB,qCAAoD;AAA3C,kHAAA,uBAAuB,OAAA;AAGhC,qCAA0C;AAAjC,wGAAA,aAAa,OAAA;AAGtB,qCAA0E;AAAjE,uGAAA,YAAY,OAAA;AAAE,wGAAA,aAAa,OAAA;AAAE,2GAAA,gBAAgB,OAAA"}
|
package/dist/payload.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
// Funciones puras: derivan el payload y el tipo de atestación a partir de la
|
|
2
3
|
// acción de SAK y su resultado. Sin efectos secundarios → fáciles de testear.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.extractSignature = extractSignature;
|
|
6
|
+
exports.mapActionType = mapActionType;
|
|
7
|
+
exports.buildPayload = buildPayload;
|
|
3
8
|
const SIGNATURE_KEYS = ['signature', 'txSignature', 'txid', 'tx'];
|
|
4
9
|
const DECISION_PATTERN = /decision|choose|select|rebalance|hold|exit|approve|reject/i;
|
|
5
10
|
/** Extrae la firma on-chain del result de una acción, si está presente. */
|
|
6
|
-
|
|
11
|
+
function extractSignature(result) {
|
|
7
12
|
for (const key of SIGNATURE_KEYS) {
|
|
8
13
|
const value = result[key];
|
|
9
14
|
if (typeof value === 'string' && value.length > 0)
|
|
@@ -12,7 +17,7 @@ export function extractSignature(result) {
|
|
|
12
17
|
return undefined;
|
|
13
18
|
}
|
|
14
19
|
/** Mapea el nombre de una acción de SAK al `ActionType` de Prova. */
|
|
15
|
-
|
|
20
|
+
function mapActionType(actionName, result) {
|
|
16
21
|
if (extractSignature(result))
|
|
17
22
|
return 'Transaction';
|
|
18
23
|
if (DECISION_PATTERN.test(actionName))
|
|
@@ -20,7 +25,7 @@ export function mapActionType(actionName, result) {
|
|
|
20
25
|
return 'ToolCall';
|
|
21
26
|
}
|
|
22
27
|
/** Construye el objeto que se serializa y hashea para producir el action_hash. */
|
|
23
|
-
|
|
28
|
+
function buildPayload(actionName, input, result) {
|
|
24
29
|
const signature = extractSignature(result);
|
|
25
30
|
if (signature) {
|
|
26
31
|
return { kind: 'transaction', action: actionName, signature, input };
|
package/dist/payload.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payload.js","sourceRoot":"","sources":["../src/payload.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,8EAA8E;
|
|
1
|
+
{"version":3,"file":"payload.js","sourceRoot":"","sources":["../src/payload.ts"],"names":[],"mappings":";AAAA,6EAA6E;AAC7E,8EAA8E;;AAQ9E,4CAMC;AAGD,sCAIC;AAGD,oCAUC;AA9BD,MAAM,cAAc,GAAG,CAAC,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,CAAU,CAAC;AAC3E,MAAM,gBAAgB,GAAG,4DAA4D,CAAC;AAEtF,2EAA2E;AAC3E,SAAgB,gBAAgB,CAAC,MAAoB;IACnD,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;IAClE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,qEAAqE;AACrE,SAAgB,aAAa,CAAC,UAAkB,EAAE,MAAoB;IACpE,IAAI,gBAAgB,CAAC,MAAM,CAAC;QAAE,OAAO,aAAa,CAAC;IACnD,IAAI,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IACzD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,kFAAkF;AAClF,SAAgB,YAAY,CAC1B,UAAkB,EAClB,KAA8B,EAC9B,MAAoB;IAEpB,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACvE,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACjE,CAAC"}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
export type TimerId = number | {
|
|
3
3
|
readonly __timer?: unique symbol;
|
|
4
4
|
};
|
|
5
|
-
/**
|
|
6
|
-
export declare function
|
|
7
|
-
export declare function
|
|
5
|
+
/** setTimeout que no bloquea la salida del proceso (unref en Node si existe). */
|
|
6
|
+
export declare function setTimeoutSafe(handler: () => void, ms: number): TimerId;
|
|
7
|
+
export declare function clearTimeoutSafe(id: TimerId): void;
|
|
8
8
|
export declare function warn(...args: unknown[]): void;
|
|
9
9
|
//# sourceMappingURL=runtime.d.ts.map
|
package/dist/runtime.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAIA,6EAA6E;AAC7E,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,MAAM,CAAA;CAAE,CAAC;AAUpE,
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAIA,6EAA6E;AAC7E,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,MAAM,CAAA;CAAE,CAAC;AAUpE,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAKvE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAElD;AAED,wBAAgB,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAE7C"}
|
package/dist/runtime.js
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
// Acceso tipado a globales de runtime (timers, console) sin depender de
|
|
2
3
|
// @types/node ni de los tipos del DOM. En ejecución real los provee Node o el
|
|
3
4
|
// navegador; aquí los declaramos mínimamente para mantener el adapter ligero.
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.setTimeoutSafe = setTimeoutSafe;
|
|
7
|
+
exports.clearTimeoutSafe = clearTimeoutSafe;
|
|
8
|
+
exports.warn = warn;
|
|
4
9
|
const runtime = globalThis;
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
const id = runtime.
|
|
10
|
+
/** setTimeout que no bloquea la salida del proceso (unref en Node si existe). */
|
|
11
|
+
function setTimeoutSafe(handler, ms) {
|
|
12
|
+
const id = runtime.setTimeout(handler, ms);
|
|
8
13
|
const maybe = id;
|
|
9
14
|
if (typeof maybe.unref === 'function')
|
|
10
15
|
maybe.unref();
|
|
11
16
|
return id;
|
|
12
17
|
}
|
|
13
|
-
|
|
14
|
-
runtime.
|
|
18
|
+
function clearTimeoutSafe(id) {
|
|
19
|
+
runtime.clearTimeout(id);
|
|
15
20
|
}
|
|
16
|
-
|
|
21
|
+
function warn(...args) {
|
|
17
22
|
runtime.console.warn(...args);
|
|
18
23
|
}
|
|
19
24
|
//# sourceMappingURL=runtime.js.map
|
package/dist/runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,8EAA8E;AAC9E,8EAA8E;
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":";AAAA,wEAAwE;AACxE,8EAA8E;AAC9E,8EAA8E;;AAc9E,wCAKC;AAED,4CAEC;AAED,oBAEC;AAhBD,MAAM,OAAO,GAAG,UAAuC,CAAC;AAExD,iFAAiF;AACjF,SAAgB,cAAc,CAAC,OAAmB,EAAE,EAAU;IAC5D,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,EAAuC,CAAC;IACtD,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,UAAU;QAAE,KAAK,CAAC,KAAK,EAAE,CAAC;IACrD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAgB,gBAAgB,CAAC,EAAW;IAC1C,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED,SAAgB,IAAI,CAAC,GAAG,IAAe;IACrC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AAChC,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -45,10 +45,14 @@ export interface ProvaAttester {
|
|
|
45
45
|
}
|
|
46
46
|
/** Configuración del batching de atestaciones. */
|
|
47
47
|
export interface BatchOptions {
|
|
48
|
-
/** Nº máximo de atestaciones por transacción (1–100). Default 25. */
|
|
48
|
+
/** Nº máximo de atestaciones por transacción (1–100). Al alcanzarlo, flush inmediato. Default 25. */
|
|
49
49
|
maxSize?: number;
|
|
50
|
-
/**
|
|
51
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Debounce: hace flush este nº de ms tras la ÚLTIMA acción. Así una ráfaga de
|
|
52
|
+
* tool calls (multi-tool-calling) se agrupa en UNA sola tx on-chain apenas
|
|
53
|
+
* termina la ráfaga. Default 1000. 0 = flush inmediato en cada acción (sin batch).
|
|
54
|
+
*/
|
|
55
|
+
flushDelayMs?: number;
|
|
52
56
|
}
|
|
53
57
|
/** Opciones de `attachProva`. */
|
|
54
58
|
export interface AttachProvaOptions {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAKA,yDAAyD;AACzD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnD,wEAAwE;AACxE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IACnF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wEAAwE;AACxE,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,+DAA+D;AAC/D,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE;QAAE,QAAQ,IAAI,MAAM,CAAA;KAAE,CAAC;IAC3C,eAAe,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC/C,mBAAmB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IACxD,sBAAsB,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7F,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACvD;AAED,6EAA6E;AAC7E,MAAM,MAAM,eAAe,GACvB,aAAa,GACb,UAAU,GACV,iBAAiB,GACjB,UAAU,GACV,gBAAgB,GAChB,aAAa,GACb,QAAQ,CAAC;AAEb,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,eAAe,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACjD,MAAM,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChE,WAAW,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzE;AAED,kDAAkD;AAClD,MAAM,WAAW,YAAY;IAC3B,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAKA,yDAAyD;AACzD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnD,wEAAwE;AACxE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IACnF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wEAAwE;AACxE,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,+DAA+D;AAC/D,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE;QAAE,QAAQ,IAAI,MAAM,CAAA;KAAE,CAAC;IAC3C,eAAe,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC/C,mBAAmB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IACxD,sBAAsB,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7F,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACvD;AAED,6EAA6E;AAC7E,MAAM,MAAM,eAAe,GACvB,aAAa,GACb,UAAU,GACV,iBAAiB,GACjB,UAAU,GACV,gBAAgB,GAChB,aAAa,GACb,QAAQ,CAAC;AAEb,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,eAAe,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACjD,MAAM,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChE,WAAW,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzE;AAED,kDAAkD;AAClD,MAAM,WAAW,YAAY;IAC3B,qGAAqG;IACrG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,iCAAiC;AACjC,MAAM,WAAW,kBAAkB;IACjC,0DAA0D;IAC1D,QAAQ,EAAE,aAAa,CAAC;IACxB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;IACxC,iCAAiC;IACjC,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACjE"}
|
package/dist/types.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
// Tipos del adapter. Reflejamos estructuralmente la API pública de Solana Agent
|
|
2
3
|
// Kit v2 (BaseWallet, Action, SolanaAgentKit) para NO importar el paquete y
|
|
3
4
|
// mantener el adapter como peerDependency ligera. La compatibilidad se apoya en
|
|
4
5
|
// el tipado estructural de TypeScript.
|
|
5
|
-
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
7
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,4EAA4E;AAC5E,gFAAgF;AAChF,uCAAuC"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,4EAA4E;AAC5E,gFAAgF;AAChF,uCAAuC"}
|
package/dist/wallet.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
// Enfoque A: decorador de BaseWallet (SAK v2). Captura la firma on-chain real
|
|
2
3
|
// de cada transacción firmada/enviada, sin importar qué plugin la produjo. Es
|
|
3
4
|
// el "cinturón de seguridad" que complementa a `attachProva`.
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ProvaWallet = void 0;
|
|
7
|
+
const batcher_1 = require("./batcher");
|
|
8
|
+
class ProvaWallet {
|
|
6
9
|
inner;
|
|
7
10
|
attester;
|
|
8
11
|
batcher;
|
|
9
12
|
constructor(inner, options) {
|
|
10
13
|
this.inner = inner;
|
|
11
14
|
this.attester = options.attester;
|
|
12
|
-
this.batcher = createBatcher(options.attester, options.batch, options.onError);
|
|
15
|
+
this.batcher = (0, batcher_1.createBatcher)(options.attester, options.batch, options.onError);
|
|
13
16
|
}
|
|
14
17
|
get publicKey() {
|
|
15
18
|
return this.inner.publicKey;
|
|
@@ -43,4 +46,5 @@ export class ProvaWallet {
|
|
|
43
46
|
this.batcher.add({ actionHash, actionType: 'Transaction' });
|
|
44
47
|
}
|
|
45
48
|
}
|
|
49
|
+
exports.ProvaWallet = ProvaWallet;
|
|
46
50
|
//# sourceMappingURL=wallet.js.map
|
package/dist/wallet.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wallet.js","sourceRoot":"","sources":["../src/wallet.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,8EAA8E;AAC9E,8DAA8D
|
|
1
|
+
{"version":3,"file":"wallet.js","sourceRoot":"","sources":["../src/wallet.ts"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,8EAA8E;AAC9E,8DAA8D;;;AAG9D,uCAAwD;AAQxD,MAAa,WAAW;IACL,KAAK,CAAa;IAClB,QAAQ,CAAgB;IACxB,OAAO,CAAU;IAElC,YAAY,KAAiB,EAAE,OAA2B;QACxD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,OAAO,GAAG,IAAA,uBAAa,EAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACjF,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;IAC9B,CAAC;IAED,eAAe,CAAI,WAAc;QAC/B,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;IACjD,CAAC;IAED,mBAAmB,CAAI,YAAiB;QACtC,OAAO,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;IACtD,CAAC;IAED,WAAW,CAAC,OAAmB;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAI,WAAc,EAAE,OAAiB;QAC/D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC7E,sDAAsD;QACtD,KAAK,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,sDAAsD;IACtD,KAAK;QACH,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC;IAED,gDAAgD;IAChD,IAAI;QACF,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,SAAiB;QAC9C,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;QACrE,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC;IAC9D,CAAC;CACF;AAjDD,kCAiDC"}
|
package/package.json
CHANGED
package/src/attach.test.ts
CHANGED
|
@@ -29,7 +29,7 @@ describe('attachProva', () => {
|
|
|
29
29
|
|
|
30
30
|
const handle = attachProva(agent, {
|
|
31
31
|
attester,
|
|
32
|
-
batch: { maxSize: 1,
|
|
32
|
+
batch: { maxSize: 1, flushDelayMs: 0 },
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
const result = await agent.actions[0]!.handler(agent, { amount: 10 });
|
|
@@ -72,7 +72,7 @@ describe('attachProva', () => {
|
|
|
72
72
|
const handle = attachProva(agent, {
|
|
73
73
|
attester,
|
|
74
74
|
rules: (name) => name === 'trade',
|
|
75
|
-
batch: { maxSize: 1,
|
|
75
|
+
batch: { maxSize: 1, flushDelayMs: 0 },
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
await agent.actions[0]!.handler(agent, {});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { createBatcher } from './batcher';
|
|
3
|
+
import type { AttestationItem, ProvaAttester } from './types';
|
|
4
|
+
|
|
5
|
+
function recordingAttester() {
|
|
6
|
+
const attests: AttestationItem[] = [];
|
|
7
|
+
const batches: AttestationItem[][] = [];
|
|
8
|
+
const attester: ProvaAttester = {
|
|
9
|
+
hashAction: async () => new Uint8Array(32),
|
|
10
|
+
attest: async (item) => {
|
|
11
|
+
attests.push(item);
|
|
12
|
+
return { txSignature: 'tx' };
|
|
13
|
+
},
|
|
14
|
+
batchAttest: async (items) => {
|
|
15
|
+
batches.push(items);
|
|
16
|
+
return { txSignature: 'tx' };
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
return { attester, attests, batches };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const item = (): AttestationItem => ({ actionHash: new Uint8Array(32), actionType: 'ToolCall' });
|
|
23
|
+
const wait = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
|
24
|
+
|
|
25
|
+
describe('createBatcher — multi-tool-calling (bug del mentor)', () => {
|
|
26
|
+
it('agrupa una RÁFAGA de 11 acciones en UNA sola batchAttest', async () => {
|
|
27
|
+
const { attester, attests, batches } = recordingAttester();
|
|
28
|
+
const batcher = createBatcher(attester, { maxSize: 25, flushDelayMs: 20 });
|
|
29
|
+
|
|
30
|
+
for (let i = 0; i < 11; i++) batcher.add(item());
|
|
31
|
+
|
|
32
|
+
await wait(50); // pasa el debounce
|
|
33
|
+
expect(batches).toHaveLength(1); // UNA sola tx
|
|
34
|
+
expect(batches[0]).toHaveLength(11); // con las 11 dentro
|
|
35
|
+
expect(attests).toHaveLength(0); // ninguna suelta
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('no pierde nada si el agente cierra antes del debounce (stop hace flush)', async () => {
|
|
39
|
+
const { attester, batches } = recordingAttester();
|
|
40
|
+
const batcher = createBatcher(attester, { maxSize: 25, flushDelayMs: 5000 });
|
|
41
|
+
|
|
42
|
+
for (let i = 0; i < 11; i++) batcher.add(item());
|
|
43
|
+
await batcher.stop(); // cierre inmediato
|
|
44
|
+
|
|
45
|
+
expect(batches).toHaveLength(1);
|
|
46
|
+
expect(batches[0]).toHaveLength(11);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('hace flush inmediato al alcanzar maxSize', async () => {
|
|
50
|
+
const { attester, batches } = recordingAttester();
|
|
51
|
+
const batcher = createBatcher(attester, { maxSize: 5, flushDelayMs: 5000 });
|
|
52
|
+
|
|
53
|
+
for (let i = 0; i < 5; i++) batcher.add(item());
|
|
54
|
+
await wait(0);
|
|
55
|
+
|
|
56
|
+
expect(batches).toHaveLength(1);
|
|
57
|
+
expect(batches[0]).toHaveLength(5);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('una sola acción usa attest (no batchAttest)', async () => {
|
|
61
|
+
const { attester, attests, batches } = recordingAttester();
|
|
62
|
+
const batcher = createBatcher(attester, { flushDelayMs: 10 });
|
|
63
|
+
|
|
64
|
+
batcher.add(item());
|
|
65
|
+
await wait(30);
|
|
66
|
+
|
|
67
|
+
expect(attests).toHaveLength(1);
|
|
68
|
+
expect(batches).toHaveLength(0);
|
|
69
|
+
});
|
|
70
|
+
});
|
package/src/batcher.ts
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
|
-
// Buffer de atestaciones
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// Buffer de atestaciones con flush por DEBOUNCE: agrupa una ráfaga de acciones
|
|
2
|
+
// (multi-tool-calling) y las envía en UNA sola tx (batchAttest, hasta 100) apenas
|
|
3
|
+
// la ráfaga se detiene. Esto arregla el bug de "N tool calls seguidos → 0 guardadas":
|
|
4
|
+
// antes el flush solo ocurría a los 25 items o cada 10s, así que una ráfaga corta
|
|
5
|
+
// que terminaba antes quedaba sin enviar.
|
|
4
6
|
|
|
5
7
|
import type { AttestationItem, BatchOptions, ProvaAttester } from './types';
|
|
6
|
-
import {
|
|
8
|
+
import { clearTimeoutSafe, setTimeoutSafe, warn, type TimerId } from './runtime';
|
|
7
9
|
|
|
8
10
|
export interface Batcher {
|
|
9
|
-
/** Encola una atestación;
|
|
11
|
+
/** Encola una atestación; programa el flush (o lo dispara si se alcanza maxSize). */
|
|
10
12
|
add(item: AttestationItem): void;
|
|
11
13
|
/** Envía inmediatamente lo pendiente. */
|
|
12
14
|
flush(): Promise<void>;
|
|
13
|
-
/**
|
|
15
|
+
/** Cancela el timer y hace un último flush (llamar al cerrar el agente). */
|
|
14
16
|
stop(): Promise<void>;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
const DEFAULT_MAX_SIZE = 25;
|
|
18
|
-
const
|
|
20
|
+
const DEFAULT_FLUSH_DELAY_MS = 1000;
|
|
19
21
|
const HARD_BATCH_LIMIT = 100;
|
|
20
22
|
|
|
21
23
|
export function createBatcher(
|
|
@@ -24,12 +26,20 @@ export function createBatcher(
|
|
|
24
26
|
onError: (error: unknown) => void = (error) => warn('[Prova] batch error:', error),
|
|
25
27
|
): Batcher {
|
|
26
28
|
const maxSize = Math.min(Math.max(options.maxSize ?? DEFAULT_MAX_SIZE, 1), HARD_BATCH_LIMIT);
|
|
27
|
-
const
|
|
29
|
+
const flushDelayMs = options.flushDelayMs ?? DEFAULT_FLUSH_DELAY_MS;
|
|
28
30
|
|
|
29
31
|
let buffer: AttestationItem[] = [];
|
|
30
32
|
let timer: TimerId | undefined;
|
|
31
33
|
|
|
34
|
+
function clearTimer(): void {
|
|
35
|
+
if (timer !== undefined) {
|
|
36
|
+
clearTimeoutSafe(timer);
|
|
37
|
+
timer = undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
32
41
|
async function flush(): Promise<void> {
|
|
42
|
+
clearTimer();
|
|
33
43
|
if (buffer.length === 0) return;
|
|
34
44
|
const batch = buffer;
|
|
35
45
|
buffer = [];
|
|
@@ -44,24 +54,29 @@ export function createBatcher(
|
|
|
44
54
|
}
|
|
45
55
|
}
|
|
46
56
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
57
|
+
// Debounce: cada acción reinicia el timer, de modo que el flush ocurre
|
|
58
|
+
// `flushDelayMs` ms DESPUÉS de la última acción de la ráfaga → todo en 1 tx.
|
|
59
|
+
function scheduleFlush(): void {
|
|
60
|
+
clearTimer();
|
|
61
|
+
if (flushDelayMs <= 0) {
|
|
62
|
+
void flush();
|
|
63
|
+
return;
|
|
50
64
|
}
|
|
65
|
+
timer = setTimeoutSafe(() => void flush(), flushDelayMs);
|
|
51
66
|
}
|
|
52
67
|
|
|
53
68
|
return {
|
|
54
69
|
add(item: AttestationItem): void {
|
|
55
70
|
buffer.push(item);
|
|
56
|
-
|
|
57
|
-
|
|
71
|
+
if (buffer.length >= maxSize) {
|
|
72
|
+
void flush(); // llegó al tope → envía ya
|
|
73
|
+
} else {
|
|
74
|
+
scheduleFlush(); // si no, agrupa la ráfaga y envía al detenerse
|
|
75
|
+
}
|
|
58
76
|
},
|
|
59
77
|
flush,
|
|
60
78
|
async stop(): Promise<void> {
|
|
61
|
-
|
|
62
|
-
clearIntervalSafe(timer);
|
|
63
|
-
timer = undefined;
|
|
64
|
-
}
|
|
79
|
+
clearTimer();
|
|
65
80
|
await flush();
|
|
66
81
|
},
|
|
67
82
|
};
|
package/src/runtime.ts
CHANGED
|
@@ -6,23 +6,23 @@
|
|
|
6
6
|
export type TimerId = number | { readonly __timer?: unique symbol };
|
|
7
7
|
|
|
8
8
|
interface RuntimeGlobals {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
setTimeout(handler: () => void, ms: number): TimerId;
|
|
10
|
+
clearTimeout(id: TimerId): void;
|
|
11
11
|
console: { warn(...args: unknown[]): void };
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
const runtime = globalThis as unknown as RuntimeGlobals;
|
|
15
15
|
|
|
16
|
-
/**
|
|
17
|
-
export function
|
|
18
|
-
const id = runtime.
|
|
16
|
+
/** setTimeout que no bloquea la salida del proceso (unref en Node si existe). */
|
|
17
|
+
export function setTimeoutSafe(handler: () => void, ms: number): TimerId {
|
|
18
|
+
const id = runtime.setTimeout(handler, ms);
|
|
19
19
|
const maybe = id as unknown as { unref?: () => void };
|
|
20
20
|
if (typeof maybe.unref === 'function') maybe.unref();
|
|
21
21
|
return id;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
export function
|
|
25
|
-
runtime.
|
|
24
|
+
export function clearTimeoutSafe(id: TimerId): void {
|
|
25
|
+
runtime.clearTimeout(id);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export function warn(...args: unknown[]): void {
|
package/src/types.ts
CHANGED
|
@@ -56,10 +56,14 @@ export interface ProvaAttester {
|
|
|
56
56
|
|
|
57
57
|
/** Configuración del batching de atestaciones. */
|
|
58
58
|
export interface BatchOptions {
|
|
59
|
-
/** Nº máximo de atestaciones por transacción (1–100). Default 25. */
|
|
59
|
+
/** Nº máximo de atestaciones por transacción (1–100). Al alcanzarlo, flush inmediato. Default 25. */
|
|
60
60
|
maxSize?: number;
|
|
61
|
-
/**
|
|
62
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Debounce: hace flush este nº de ms tras la ÚLTIMA acción. Así una ráfaga de
|
|
63
|
+
* tool calls (multi-tool-calling) se agrupa en UNA sola tx on-chain apenas
|
|
64
|
+
* termina la ráfaga. Default 1000. 0 = flush inmediato en cada acción (sin batch).
|
|
65
|
+
*/
|
|
66
|
+
flushDelayMs?: number;
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
/** Opciones de `attachProva`. */
|