agentex-creator-sdk 1.0.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/CHANGELOG.md +36 -0
- package/LICENSE +21 -0
- package/README.md +195 -0
- package/dist/packages/contracts/src/deployer-investigation.d.ts +1015 -0
- package/dist/packages/contracts/src/deployer-investigation.js +101 -0
- package/dist/packages/contracts/src/index.d.ts +1701 -0
- package/dist/packages/contracts/src/index.js +380 -0
- package/dist/packages/contracts/src/indexed-activity.d.ts +684 -0
- package/dist/packages/contracts/src/indexed-activity.js +71 -0
- package/dist/packages/contracts/src/indexed-agents.d.ts +299 -0
- package/dist/packages/contracts/src/indexed-agents.js +131 -0
- package/dist/packages/contracts/src/inspection.d.ts +906 -0
- package/dist/packages/contracts/src/inspection.js +114 -0
- package/dist/packages/contracts/src/kinds.d.ts +5398 -0
- package/dist/packages/contracts/src/kinds.js +156 -0
- package/dist/packages/contracts/src/report-presentation.d.ts +346 -0
- package/dist/packages/contracts/src/report-presentation.js +120 -0
- package/dist/packages/contracts/src/solana-inspection.d.ts +451 -0
- package/dist/packages/contracts/src/solana-inspection.js +94 -0
- package/dist/packages/contracts/src/token-market.d.ts +193 -0
- package/dist/packages/contracts/src/token-market.js +335 -0
- package/dist/packages/contracts/src/wallet-analysis.d.ts +866 -0
- package/dist/packages/contracts/src/wallet-analysis.js +89 -0
- package/dist/packages/contracts/src/watchtower.d.ts +1141 -0
- package/dist/packages/contracts/src/watchtower.js +196 -0
- package/dist/packages/contracts/src/workflow.d.ts +1568 -0
- package/dist/packages/contracts/src/workflow.js +651 -0
- package/dist/packages/inspector/src/decode.d.ts +23 -0
- package/dist/packages/inspector/src/decode.js +150 -0
- package/dist/packages/inspector/src/scope.d.ts +87 -0
- package/dist/packages/inspector/src/scope.js +64 -0
- package/dist/packages/model/src/analysis.d.ts +149 -0
- package/dist/packages/model/src/analysis.js +387 -0
- package/dist/packages/model/src/pricing.d.ts +38 -0
- package/dist/packages/model/src/pricing.js +49 -0
- package/dist/packages/model/src/retry.d.ts +20 -0
- package/dist/packages/model/src/retry.js +31 -0
- package/dist/packages/model/src/schema.d.ts +10 -0
- package/dist/packages/model/src/schema.js +51 -0
- package/dist/packages/model/src/summary.d.ts +91 -0
- package/dist/packages/model/src/summary.js +177 -0
- package/dist/packages/model/src/types.d.ts +81 -0
- package/dist/packages/model/src/types.js +19 -0
- package/dist/packages/monitoring/src/delivery.d.ts +32 -0
- package/dist/packages/monitoring/src/delivery.js +53 -0
- package/dist/packages/providers/src/chain-transport.d.ts +42 -0
- package/dist/packages/providers/src/chain-transport.js +57 -0
- package/dist/packages/providers/src/coverage.d.ts +105 -0
- package/dist/packages/providers/src/coverage.js +260 -0
- package/dist/packages/providers/src/health.d.ts +273 -0
- package/dist/packages/providers/src/health.js +505 -0
- package/dist/packages/providers/src/keyed.d.ts +96 -0
- package/dist/packages/providers/src/keyed.js +240 -0
- package/dist/packages/providers/src/snapshot.d.ts +61 -0
- package/dist/packages/providers/src/snapshot.js +77 -0
- package/dist/packages/publication/src/fixtures.d.ts +45 -0
- package/dist/packages/publication/src/fixtures.js +350 -0
- package/dist/packages/research/src/index.d.ts +188 -0
- package/dist/packages/research/src/index.js +829 -0
- package/dist/packages/runtime/src/checkpoints.d.ts +65 -0
- package/dist/packages/runtime/src/checkpoints.js +214 -0
- package/dist/packages/runtime/src/policy.d.ts +57 -0
- package/dist/packages/runtime/src/policy.js +296 -0
- package/dist/packages/sdk/src/bin/agentex-buyer.d.ts +2 -0
- package/dist/packages/sdk/src/bin/agentex-buyer.js +4 -0
- package/dist/packages/sdk/src/bin/agentex.d.ts +2 -0
- package/dist/packages/sdk/src/bin/agentex.js +3 -0
- package/dist/packages/sdk/src/buyer-cli.d.ts +10 -0
- package/dist/packages/sdk/src/buyer-cli.js +210 -0
- package/dist/packages/sdk/src/buyer.d.ts +534 -0
- package/dist/packages/sdk/src/buyer.js +441 -0
- package/dist/packages/sdk/src/cli.d.ts +14 -0
- package/dist/packages/sdk/src/cli.js +149 -0
- package/dist/packages/sdk/src/errors.d.ts +31 -0
- package/dist/packages/sdk/src/errors.js +24 -0
- package/dist/packages/sdk/src/index.d.ts +236 -0
- package/dist/packages/sdk/src/index.js +150 -0
- package/dist/packages/sdk/src/local.d.ts +11 -0
- package/dist/packages/sdk/src/local.js +110 -0
- package/dist/packages/sdk/src/rails.d.ts +59 -0
- package/dist/packages/sdk/src/rails.js +96 -0
- package/dist/packages/sdk/src/report.d.ts +121 -0
- package/dist/packages/sdk/src/report.js +114 -0
- package/dist/packages/sdk/src/version.d.ts +2 -0
- package/dist/packages/sdk/src/version.js +2 -0
- package/dist/packages/watchtower/src/index.d.ts +150 -0
- package/dist/packages/watchtower/src/index.js +786 -0
- package/dist/packages/workflow/src/registry.d.ts +61 -0
- package/dist/packages/workflow/src/registry.js +76 -0
- package/examples/README.md +34 -0
- package/examples/cli-usage.sh +30 -0
- package/examples/fixtures/base-weth-input.json +4 -0
- package/examples/focused-researcher.json +127 -0
- package/examples/pay-with-eth-robinhood.mts +37 -0
- package/examples/pay-with-usdc.mts +41 -0
- package/examples/quickstart.mts +73 -0
- package/package.json +50 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Shared output shapes of the indexed activity tools (packages/tools `evm.contract-origin`, `evm.address-funding`, `evm.deployer-launches`,
|
|
4
|
+
* `evm.wallet-activity`) and of the reports that embed them (P02 Deployer Investigator, P03 Wallet Analyst). They live here so report
|
|
5
|
+
* contracts validate without tool implementations and the two can never drift.
|
|
6
|
+
*/
|
|
7
|
+
export const ACTIVITY_TOOL_REFS = Object.freeze({ origin: 'evm.contract-origin@0.1.0', funding: 'evm.address-funding@0.1.0', launches: 'evm.deployer-launches@0.1.0', wallet: 'evm.wallet-activity@0.1.0' });
|
|
8
|
+
// R02: `debug_traceTransaction` (fixed prestate-diff tracer) verifies a contract's creation inside its transaction and names the contract that ran the CREATE.
|
|
9
|
+
export const ACTIVITY_READ_METHODS = Object.freeze(['eth_chainId', 'eth_getBlockByNumber', 'eth_getCode', 'eth_getBalance', 'eth_getTransactionReceipt', 'alchemy_getAssetTransfers', 'alchemy_getTokenBalances', 'alchemy_getTokenMetadata', 'debug_traceTransaction']);
|
|
10
|
+
const Exact = z.string().regex(/^(0|[1-9][0-9]{0,77})$/);
|
|
11
|
+
const Hex32 = z.string().regex(/^0x[a-fA-F0-9]{64}$/);
|
|
12
|
+
const Address = z.string().regex(/^0x[a-fA-F0-9]{40}$/);
|
|
13
|
+
export const ActivityEvidenceIdSchema = z.string().regex(/^ev-[a-f0-9]{32}$/, 'Evidence ids are content-derived (ev- and 32 hex characters).');
|
|
14
|
+
/** Same vocabulary as the tools' `FactSchema`: unknown, unavailable (no source), not-detected (probed and empty) and error are never collapsed. */
|
|
15
|
+
export const ActivityFactSchema = z.discriminatedUnion('status', [
|
|
16
|
+
z.strictObject({ status: z.literal('observed'), value: z.union([z.string().max(4096), z.number(), z.boolean(), z.null()]), evidenceIds: z.array(ActivityEvidenceIdSchema).min(1), note: z.string().max(500).optional() }),
|
|
17
|
+
z.strictObject({ status: z.enum(['not-detected', 'unknown', 'unavailable', 'error', 'not-applicable']), reason: z.string().min(1).max(500), evidenceIds: z.array(ActivityEvidenceIdSchema) }),
|
|
18
|
+
]);
|
|
19
|
+
export const ActivityToolErrorSchema = z.strictObject({ category: z.string().regex(/^[a-z][a-z-]{1,63}$/), step: z.string().min(1).max(64), evidenceId: ActivityEvidenceIdSchema.nullable() });
|
|
20
|
+
/** `direct-transaction-evidence`: a receipt, archive state or transaction field states it. `heuristic-association`: an inference such as an event naming an address. */
|
|
21
|
+
export const ActivityFindingSchema = z.strictObject({ code: z.string().regex(/^[a-z][a-z0-9-]{1,63}$/), message: z.string().max(1000), basis: z.enum(['direct-transaction-evidence', 'heuristic-association', 'provider-index-assertion']), evidenceIds: z.array(ActivityEvidenceIdSchema) });
|
|
22
|
+
const Errors = z.array(ActivityToolErrorSchema).max(24);
|
|
23
|
+
const Findings = z.array(ActivityFindingSchema).max(32);
|
|
24
|
+
export const ACTIVITY_CATEGORIES = ['external', 'internal', 'erc20', 'erc721', 'erc1155'];
|
|
25
|
+
export const ActivityCategorySchema = z.enum(ACTIVITY_CATEGORIES);
|
|
26
|
+
export const ActivityTransferSchema = z.strictObject({
|
|
27
|
+
direction: z.enum(['in', 'out']), category: ActivityCategorySchema, blockNumber: Exact, blockTimestamp: z.string().max(40).nullable(), transactionHash: Hex32, uniqueId: z.string().max(128),
|
|
28
|
+
from: Address, to: Address.nullable(), asset: z.string().max(64).nullable(), contract: Address.nullable(), tokenId: z.string().max(80).nullable(),
|
|
29
|
+
valueAtomic: Exact.nullable(), decimals: z.number().int().min(0).max(255).nullable(), valueFormatted: z.string().max(340).nullable(),
|
|
30
|
+
decimalsSource: z.enum(['native-18', 'provider-raw-contract', 'not-applicable', 'not-reported']), selfTransfer: z.boolean(), evidenceId: ActivityEvidenceIdSchema,
|
|
31
|
+
});
|
|
32
|
+
export const TransferPageStatusSchema = z.enum(['provider-exhausted', 'truncated-with-cursor', 'unavailable', 'not-read-call-bound']);
|
|
33
|
+
export const TransferPageSchema = z.strictObject({ direction: z.enum(['in', 'out']), index: z.number().int().min(0).max(4), returned: z.number().int().nonnegative(), nextPageKey: z.string().max(256).nullable(), status: TransferPageStatusSchema, evidenceId: ActivityEvidenceIdSchema.nullable() });
|
|
34
|
+
const OriginRoleSchema = z.strictObject({ address: Address, role: z.enum(['deployment-transaction-sender', 'creation-entry-target', 'factory-event-emitter', 'erc4337-entrypoint', 'trace-verified-creator', 'creation-candidate']), isPerson: z.literal(false), label: z.string().max(100).nullable(), basis: z.string().max(400), evidenceIds: z.array(ActivityEvidenceIdSchema) });
|
|
35
|
+
export const ContractOriginBodySchema = z.strictObject({
|
|
36
|
+
contract: Address, chain: z.string(), codeAtSnapshot: ActivityFactSchema,
|
|
37
|
+
creation: z.strictObject({
|
|
38
|
+
status: z.enum(['confirmed-by-receipt', 'block-located', 'bounded-range', 'not-located', 'no-code-at-snapshot', 'unavailable']),
|
|
39
|
+
blockNumber: ActivityFactSchema, transactionHash: ActivityFactSchema, transactionBasis: z.enum(['receipt-contract-address', 'trace-verified-creation', 'first-indexed-activity-in-creation-block', 'not-established']),
|
|
40
|
+
createdBy: z.enum(['top-level-transaction', 'contract-call-in-transaction', 'not-established']),
|
|
41
|
+
anchor: z.strictObject({ source: z.enum(['supplied-transaction', 'first-indexed-token-transfer', 'first-indexed-inbound-call', 'none']), transactionHash: Hex32.nullable(), blockNumber: Exact.nullable(), evidenceIds: z.array(ActivityEvidenceIdSchema) }),
|
|
42
|
+
range: z.strictObject({ from: Exact, to: Exact }).nullable(), probes: z.number().int().min(0).max(8), codeBeforeCreation: ActivityFactSchema, codeAtCreationBlock: ActivityFactSchema,
|
|
43
|
+
}),
|
|
44
|
+
initiator: ActivityFactSchema, entryTarget: ActivityFactSchema, factoryEventEmitters: z.array(z.strictObject({ address: Address, label: z.string().max(100).nullable(), evidenceIds: z.array(ActivityEvidenceIdSchema).min(1) })).max(4),
|
|
45
|
+
roles: z.array(OriginRoleSchema).max(8), findings: Findings, errors: Errors,
|
|
46
|
+
});
|
|
47
|
+
const FunderSchema = z.strictObject({ funder: Address, label: z.string().max(100).nullable(), isPerson: z.literal(false), transfers: z.number().int().positive(), nativeAtomic: Exact, nativeFormatted: z.string().max(120), tokenTransfers: z.number().int().nonnegative(),
|
|
48
|
+
firstBlock: Exact, firstTransactionHash: Hex32, evidenceIds: z.array(ActivityEvidenceIdSchema).min(1) });
|
|
49
|
+
export const AddressFundingBodySchema = z.strictObject({
|
|
50
|
+
address: Address, chain: z.string(), transfers: z.array(ActivityTransferSchema).max(100), funders: z.array(FunderSchema).max(100), pages: z.array(TransferPageSchema).max(4),
|
|
51
|
+
coverage: z.strictObject({ order: z.literal('oldest-first'), categories: z.array(ActivityCategorySchema), exhausted: z.boolean(), nextPageKey: z.string().max(256).nullable(), completeness: z.literal('provider-index-claim') }),
|
|
52
|
+
interpretation: z.literal('observed-transfer-not-ownership'), findings: Findings, errors: Errors,
|
|
53
|
+
});
|
|
54
|
+
const DeploymentSchema = z.strictObject({ transactionHash: Hex32, blockNumber: Exact, blockTimestamp: z.string().max(40).nullable(), contractAddress: ActivityFactSchema, succeeded: ActivityFactSchema, isSubject: z.boolean(), evidenceIds: z.array(ActivityEvidenceIdSchema).min(1) });
|
|
55
|
+
export const DeployerLaunchesBodySchema = z.strictObject({
|
|
56
|
+
deployer: Address, chain: z.string(), window: z.strictObject({ fromBlock: Exact, toBlock: Exact }), deployments: z.array(DeploymentSchema).max(100), pages: z.array(TransferPageSchema).max(4),
|
|
57
|
+
coverage: z.strictObject({ transactionsExamined: z.number().int().nonnegative(), creationTransactions: z.number().int().nonnegative(), receiptsRead: z.number().int().nonnegative(), exhausted: z.boolean(), nextPageKey: z.string().max(256).nullable(), completeness: z.literal('provider-index-claim') }),
|
|
58
|
+
interpretation: z.literal('same-sender-deployments-not-common-control'), findings: Findings, errors: Errors,
|
|
59
|
+
});
|
|
60
|
+
const FlowSchema = z.strictObject({ asset: z.string().max(64), contract: Address.nullable(), category: ActivityCategorySchema, symbol: z.string().max(64).nullable(), decimals: z.number().int().min(0).max(255).nullable(),
|
|
61
|
+
inboundAtomic: Exact, outboundAtomic: Exact, inboundFormatted: z.string().max(340).nullable(), outboundFormatted: z.string().max(340).nullable(), transfersIn: z.number().int().nonnegative(), transfersOut: z.number().int().nonnegative(), selfTransfers: z.number().int().nonnegative(), unquantifiedTransfers: z.number().int().nonnegative() });
|
|
62
|
+
const TransactionSchema = z.strictObject({ transactionHash: Hex32, blockNumber: Exact, blockTimestamp: z.string().max(40).nullable(), legsIn: z.number().int().nonnegative(), legsOut: z.number().int().nonnegative(),
|
|
63
|
+
classification: z.enum(['inbound-only', 'outbound-only', 'self-transfer', 'in-and-out-same-transaction']), note: z.string().max(300) });
|
|
64
|
+
const TokenBalanceSchema = z.strictObject({ contract: Address, balanceAtomic: Exact.nullable(), symbol: ActivityFactSchema, decimals: ActivityFactSchema, balanceFormatted: z.string().max(340).nullable(), evidenceIds: z.array(ActivityEvidenceIdSchema).min(1) });
|
|
65
|
+
export const WalletActivityBodySchema = z.strictObject({
|
|
66
|
+
wallet: Address, chain: z.string(), window: z.strictObject({ fromBlock: Exact, toBlock: Exact }), nativeBalance: z.strictObject({ balanceAtomic: ActivityFactSchema, balanceFormatted: z.string().max(120).nullable() }),
|
|
67
|
+
transfers: z.array(ActivityTransferSchema).max(200), pages: z.array(TransferPageSchema).max(4), flows: z.array(FlowSchema).max(200), transactions: z.array(TransactionSchema).max(200),
|
|
68
|
+
tokenBalances: z.strictObject({ status: z.enum(['observed', 'not-read', 'unavailable']), finality: z.literal('provider-latest-not-pinned'), balances: z.array(TokenBalanceSchema).max(100), nextPageKey: z.string().max(256).nullable(), evidenceIds: z.array(ActivityEvidenceIdSchema) }),
|
|
69
|
+
coverage: z.strictObject({ order: z.enum(['newest-first', 'oldest-first']), categories: z.array(ActivityCategorySchema), inbound: TransferPageStatusSchema, outbound: TransferPageStatusSchema, completeness: z.literal('provider-index-claim') }),
|
|
70
|
+
findings: Findings, labelChecks: z.array(z.strictObject({ code: z.string().max(64), message: z.string().max(1000), evidenceIds: z.array(ActivityEvidenceIdSchema) })).max(32), errors: Errors,
|
|
71
|
+
});
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ResearchAnalysisSchema } from './index.js';
|
|
3
|
+
import { type ToolEvidenceItem } from './workflow.js';
|
|
4
|
+
/**
|
|
5
|
+
* Shared manifest and report rules for the indexed first-party agents (P02 Deployer Investigator, P03 Wallet Analyst). Their manifests use
|
|
6
|
+
* their own strict schema (like the Solana inspector), so `AgentManifestSchema` and every stored manifest hash stay unchanged. Every run is
|
|
7
|
+
* bounded by the paid RPC ceiling of 16 metered calls, pins one latest block (sequencer-confirmed) and rechecks it at completion.
|
|
8
|
+
*/
|
|
9
|
+
export declare const INDEXED_AGENT_CHAINS: readonly ["ethereum", "base"];
|
|
10
|
+
export declare const IndexedAgentChainSchema: z.ZodEnum<{
|
|
11
|
+
ethereum: "ethereum";
|
|
12
|
+
base: "base";
|
|
13
|
+
}>;
|
|
14
|
+
export declare const INDEXED_AGENT_RPC_CEILING = 16;
|
|
15
|
+
export declare const Hex32Schema: z.ZodString;
|
|
16
|
+
export declare const BlockNumberInputSchema: z.ZodString;
|
|
17
|
+
export declare function indexedManifestSchema<Id extends string>(outputSchemaId: Id): z.ZodObject<{
|
|
18
|
+
schemaVersion: z.ZodLiteral<"1.0">;
|
|
19
|
+
id: z.ZodString;
|
|
20
|
+
version: z.ZodString;
|
|
21
|
+
name: z.ZodString;
|
|
22
|
+
description: z.ZodString;
|
|
23
|
+
author: z.ZodObject<{
|
|
24
|
+
id: z.ZodString;
|
|
25
|
+
name: z.ZodString;
|
|
26
|
+
ownership: z.ZodEnum<{
|
|
27
|
+
"first-party": "first-party";
|
|
28
|
+
independent: "independent";
|
|
29
|
+
}>;
|
|
30
|
+
}, z.core.$strict>;
|
|
31
|
+
license: z.ZodString;
|
|
32
|
+
visibility: z.ZodEnum<{
|
|
33
|
+
private: "private";
|
|
34
|
+
"source-visible": "source-visible";
|
|
35
|
+
"source-private": "source-private";
|
|
36
|
+
}>;
|
|
37
|
+
chains: z.ZodArray<z.ZodEnum<{
|
|
38
|
+
ethereum: "ethereum";
|
|
39
|
+
base: "base";
|
|
40
|
+
}>>;
|
|
41
|
+
inputSchema: z.ZodObject<{
|
|
42
|
+
type: z.ZodLiteral<"object">;
|
|
43
|
+
properties: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
44
|
+
type: z.ZodEnum<{
|
|
45
|
+
string: "string";
|
|
46
|
+
number: "number";
|
|
47
|
+
boolean: "boolean";
|
|
48
|
+
array: "array";
|
|
49
|
+
integer: "integer";
|
|
50
|
+
}>;
|
|
51
|
+
description: z.ZodString;
|
|
52
|
+
enum: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
53
|
+
}, z.core.$strict>>;
|
|
54
|
+
required: z.ZodArray<z.ZodString>;
|
|
55
|
+
additionalProperties: z.ZodLiteral<false>;
|
|
56
|
+
}, z.core.$strict>;
|
|
57
|
+
outputSchemaId: z.ZodLiteral<Id>;
|
|
58
|
+
tools: z.ZodArray<z.ZodObject<{
|
|
59
|
+
id: z.ZodString;
|
|
60
|
+
version: z.ZodString;
|
|
61
|
+
capability: z.ZodLiteral<"evm.read">;
|
|
62
|
+
chains: z.ZodArray<z.ZodEnum<{
|
|
63
|
+
ethereum: "ethereum";
|
|
64
|
+
base: "base";
|
|
65
|
+
}>>;
|
|
66
|
+
addressScope: z.ZodLiteral<"input-address">;
|
|
67
|
+
maximumCalls: z.ZodNumber;
|
|
68
|
+
}, z.core.$strict>>;
|
|
69
|
+
modelPolicy: z.ZodObject<{
|
|
70
|
+
mode: z.ZodLiteral<"deterministic">;
|
|
71
|
+
maximumModelTokens: z.ZodLiteral<0>;
|
|
72
|
+
}, z.core.$strict>;
|
|
73
|
+
policy: z.ZodOptional<z.ZodObject<{
|
|
74
|
+
analysis: z.ZodObject<{
|
|
75
|
+
mode: z.ZodLiteral<"summary">;
|
|
76
|
+
maximumOutputTokens: z.ZodNumber;
|
|
77
|
+
maximumCostMicrousd: z.ZodNumber;
|
|
78
|
+
}, z.core.$strict>;
|
|
79
|
+
}, z.core.$strict>>;
|
|
80
|
+
limits: z.ZodObject<{
|
|
81
|
+
maximumRpcCalls: z.ZodNumber;
|
|
82
|
+
maximumDurationMs: z.ZodNumber;
|
|
83
|
+
maximumOutputBytes: z.ZodNumber;
|
|
84
|
+
maximumGraphDepth: z.ZodNumber;
|
|
85
|
+
maximumPages: z.ZodNumber;
|
|
86
|
+
maximumExecutionAtomic: z.ZodString;
|
|
87
|
+
}, z.core.$strict>;
|
|
88
|
+
workflow: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
89
|
+
type: z.ZodLiteral<"input">;
|
|
90
|
+
id: z.ZodString;
|
|
91
|
+
dependsOn: z.ZodArray<z.ZodString>;
|
|
92
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
93
|
+
type: z.ZodLiteral<"tool">;
|
|
94
|
+
tool: z.ZodString;
|
|
95
|
+
arguments: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
96
|
+
source: z.ZodLiteral<"input">;
|
|
97
|
+
path: z.ZodString;
|
|
98
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
99
|
+
source: z.ZodLiteral<"node">;
|
|
100
|
+
nodeId: z.ZodString;
|
|
101
|
+
path: z.ZodString;
|
|
102
|
+
}, z.core.$strict>], "source">>;
|
|
103
|
+
id: z.ZodString;
|
|
104
|
+
dependsOn: z.ZodArray<z.ZodString>;
|
|
105
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
106
|
+
type: z.ZodLiteral<"condition">;
|
|
107
|
+
field: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
108
|
+
source: z.ZodLiteral<"input">;
|
|
109
|
+
path: z.ZodString;
|
|
110
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
111
|
+
source: z.ZodLiteral<"node">;
|
|
112
|
+
nodeId: z.ZodString;
|
|
113
|
+
path: z.ZodString;
|
|
114
|
+
}, z.core.$strict>], "source">;
|
|
115
|
+
operator: z.ZodEnum<{
|
|
116
|
+
equals: "equals";
|
|
117
|
+
exists: "exists";
|
|
118
|
+
}>;
|
|
119
|
+
value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean, z.ZodNumber]>>;
|
|
120
|
+
whenTrue: z.ZodString;
|
|
121
|
+
whenFalse: z.ZodString;
|
|
122
|
+
id: z.ZodString;
|
|
123
|
+
dependsOn: z.ZodArray<z.ZodString>;
|
|
124
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
125
|
+
type: z.ZodLiteral<"output">;
|
|
126
|
+
from: z.ZodString;
|
|
127
|
+
id: z.ZodString;
|
|
128
|
+
dependsOn: z.ZodArray<z.ZodString>;
|
|
129
|
+
}, z.core.$strict>], "type">>;
|
|
130
|
+
testCases: z.ZodArray<z.ZodString>;
|
|
131
|
+
}, z.core.$strict>;
|
|
132
|
+
type IndexedManifestShape = z.infer<ReturnType<typeof indexedManifestSchema<string>>>;
|
|
133
|
+
/** Executable subset: the fixed graph, the template's tool references and input declaration, and a run budget that fits the minimum plan. */
|
|
134
|
+
export declare function indexedManifestIssues(manifest: IndexedManifestShape, template: IndexedManifestShape, minimumRpcCalls: number): {
|
|
135
|
+
path: (string | number)[];
|
|
136
|
+
message: string;
|
|
137
|
+
}[];
|
|
138
|
+
export declare const IndexedSnapshotSchema: z.ZodObject<{
|
|
139
|
+
blockNumber: z.ZodString;
|
|
140
|
+
blockHash: z.ZodString;
|
|
141
|
+
timestamp: z.ZodString;
|
|
142
|
+
finality: z.ZodLiteral<"sequencer-confirmed">;
|
|
143
|
+
canonicality: z.ZodEnum<{
|
|
144
|
+
"verified-at-completion": "verified-at-completion";
|
|
145
|
+
unchecked: "unchecked";
|
|
146
|
+
changed: "changed";
|
|
147
|
+
}>;
|
|
148
|
+
}, z.core.$strict>;
|
|
149
|
+
export declare const IndexedReportErrorSchema: z.ZodObject<{
|
|
150
|
+
category: z.ZodString;
|
|
151
|
+
message: z.ZodString;
|
|
152
|
+
step: z.ZodString;
|
|
153
|
+
evidenceId: z.ZodOptional<z.ZodString>;
|
|
154
|
+
}, z.core.$strict>;
|
|
155
|
+
export declare const IndexedUsageSchema: z.ZodObject<{
|
|
156
|
+
rpcCalls: z.ZodNumber;
|
|
157
|
+
maximumRpcCalls: z.ZodNumber;
|
|
158
|
+
elapsedMs: z.ZodNumber;
|
|
159
|
+
modelTokens: z.ZodLiteral<0>;
|
|
160
|
+
providerCostAtomic: z.ZodNull;
|
|
161
|
+
providerCostStatus: z.ZodLiteral<"unpriced">;
|
|
162
|
+
model: z.ZodOptional<z.ZodObject<{
|
|
163
|
+
model: z.ZodString;
|
|
164
|
+
inputTokens: z.ZodNumber;
|
|
165
|
+
outputTokens: z.ZodNumber;
|
|
166
|
+
costMicrousd: z.ZodNumber;
|
|
167
|
+
costStatus: z.ZodOptional<z.ZodLiteral<"unresolved">>;
|
|
168
|
+
}, z.core.$strict>>;
|
|
169
|
+
}, z.core.$strict>;
|
|
170
|
+
export declare const IndexedEvidenceSchema: z.ZodArray<z.ZodObject<{
|
|
171
|
+
schemaVersion: z.ZodLiteral<"agentex.tool-evidence.v1">;
|
|
172
|
+
id: z.ZodString;
|
|
173
|
+
tool: z.ZodString;
|
|
174
|
+
capability: z.ZodEnum<{
|
|
175
|
+
"evm.read": "evm.read";
|
|
176
|
+
"http.read": "http.read";
|
|
177
|
+
"solana.read": "solana.read";
|
|
178
|
+
}>;
|
|
179
|
+
source: z.ZodObject<{
|
|
180
|
+
kind: z.ZodEnum<{
|
|
181
|
+
rpc: "rpc";
|
|
182
|
+
http: "http";
|
|
183
|
+
offline: "offline";
|
|
184
|
+
}>;
|
|
185
|
+
provider: z.ZodString;
|
|
186
|
+
method: z.ZodString;
|
|
187
|
+
documentationUrl: z.ZodNullable<z.ZodURL>;
|
|
188
|
+
}, z.core.$strict>;
|
|
189
|
+
chain: z.ZodString;
|
|
190
|
+
scope: z.ZodObject<{
|
|
191
|
+
subjects: z.ZodArray<z.ZodString>;
|
|
192
|
+
window: z.ZodNullable<z.ZodObject<{
|
|
193
|
+
unit: z.ZodEnum<{
|
|
194
|
+
block: "block";
|
|
195
|
+
slot: "slot";
|
|
196
|
+
}>;
|
|
197
|
+
from: z.ZodString;
|
|
198
|
+
to: z.ZodString;
|
|
199
|
+
}, z.core.$strict>>;
|
|
200
|
+
page: z.ZodNullable<z.ZodObject<{
|
|
201
|
+
index: z.ZodNumber;
|
|
202
|
+
size: z.ZodNumber;
|
|
203
|
+
cursor: z.ZodNullable<z.ZodString>;
|
|
204
|
+
}, z.core.$strict>>;
|
|
205
|
+
}, z.core.$strict>;
|
|
206
|
+
request: z.ZodJSONSchema;
|
|
207
|
+
snapshot: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
208
|
+
kind: z.ZodLiteral<"evm-block">;
|
|
209
|
+
chainId: z.ZodNumber;
|
|
210
|
+
blockNumber: z.ZodString;
|
|
211
|
+
blockHash: z.ZodString;
|
|
212
|
+
timestamp: z.ZodNullable<z.ZodString>;
|
|
213
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
214
|
+
kind: z.ZodLiteral<"solana-slot">;
|
|
215
|
+
genesisHash: z.ZodString;
|
|
216
|
+
slot: z.ZodString;
|
|
217
|
+
commitment: z.ZodEnum<{
|
|
218
|
+
finalized: "finalized";
|
|
219
|
+
confirmed: "confirmed";
|
|
220
|
+
}>;
|
|
221
|
+
exactness: z.ZodEnum<{
|
|
222
|
+
"observed-context": "observed-context";
|
|
223
|
+
"lower-bound": "lower-bound";
|
|
224
|
+
}>;
|
|
225
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
226
|
+
kind: z.ZodLiteral<"http-retrieval">;
|
|
227
|
+
retrievedAt: z.ZodISODateTime;
|
|
228
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
229
|
+
kind: z.ZodLiteral<"offline-input">;
|
|
230
|
+
inputHash: z.ZodString;
|
|
231
|
+
}, z.core.$strict>], "kind">>;
|
|
232
|
+
observedAt: z.ZodISODateTime;
|
|
233
|
+
finality: z.ZodEnum<{
|
|
234
|
+
finalized: "finalized";
|
|
235
|
+
"sequencer-confirmed": "sequencer-confirmed";
|
|
236
|
+
unverified: "unverified";
|
|
237
|
+
"not-applicable": "not-applicable";
|
|
238
|
+
confirmed: "confirmed";
|
|
239
|
+
"finalized-lower-bound": "finalized-lower-bound";
|
|
240
|
+
"confirmed-lower-bound": "confirmed-lower-bound";
|
|
241
|
+
}>;
|
|
242
|
+
canonicality: z.ZodEnum<{
|
|
243
|
+
"verified-at-completion": "verified-at-completion";
|
|
244
|
+
unchecked: "unchecked";
|
|
245
|
+
changed: "changed";
|
|
246
|
+
"not-applicable": "not-applicable";
|
|
247
|
+
}>;
|
|
248
|
+
completeness: z.ZodEnum<{
|
|
249
|
+
error: "error";
|
|
250
|
+
"complete-for-request": "complete-for-request";
|
|
251
|
+
unavailable: "unavailable";
|
|
252
|
+
truncated: "truncated";
|
|
253
|
+
"empty-result": "empty-result";
|
|
254
|
+
}>;
|
|
255
|
+
errorCategory: z.ZodNullable<z.ZodString>;
|
|
256
|
+
result: z.ZodJSONSchema;
|
|
257
|
+
contentHash: z.ZodString;
|
|
258
|
+
artifactHash: z.ZodString;
|
|
259
|
+
privacy: z.ZodEnum<{
|
|
260
|
+
"public-chain-data": "public-chain-data";
|
|
261
|
+
"public-web-content": "public-web-content";
|
|
262
|
+
"private-input": "private-input";
|
|
263
|
+
}>;
|
|
264
|
+
trust: z.ZodEnum<{
|
|
265
|
+
"chain-state": "chain-state";
|
|
266
|
+
"provider-assertion": "provider-assertion";
|
|
267
|
+
"untrusted-third-party-content": "untrusted-third-party-content";
|
|
268
|
+
"offline-decoding": "offline-decoding";
|
|
269
|
+
}>;
|
|
270
|
+
}, z.core.$strict>>;
|
|
271
|
+
export { ResearchAnalysisSchema as IndexedAnalysisSchema };
|
|
272
|
+
export declare const NotComputedSchema: z.ZodObject<{
|
|
273
|
+
status: z.ZodLiteral<"not-computed">;
|
|
274
|
+
reason: z.ZodString;
|
|
275
|
+
sourceGap: z.ZodEnum<{
|
|
276
|
+
"historical-prices": "historical-prices";
|
|
277
|
+
"trade-classification": "trade-classification";
|
|
278
|
+
"transaction-fees": "transaction-fees";
|
|
279
|
+
}>;
|
|
280
|
+
}, z.core.$strict>;
|
|
281
|
+
type ReportCore = {
|
|
282
|
+
status: string;
|
|
283
|
+
input: {
|
|
284
|
+
chain: string;
|
|
285
|
+
};
|
|
286
|
+
snapshot: {
|
|
287
|
+
canonicality: string;
|
|
288
|
+
} | null;
|
|
289
|
+
evidence: ToolEvidenceItem[];
|
|
290
|
+
analysis?: z.infer<typeof ResearchAnalysisSchema> | undefined;
|
|
291
|
+
usage: z.infer<typeof IndexedUsageSchema>;
|
|
292
|
+
};
|
|
293
|
+
/** Envelope, provenance, budget and AI-summary rules shared by both report schemas. */
|
|
294
|
+
export declare function indexedReportIssues(report: ReportCore, allowedTools: readonly string[], ctx: z.RefinementCtx): void;
|
|
295
|
+
/** Checkpoint receipt scope for indexed agents: a declared tool, the read-method allowlist, the accepted chain and an intact envelope. */
|
|
296
|
+
export declare function validateIndexedReceipt(evidence: unknown, input: {
|
|
297
|
+
chain: string;
|
|
298
|
+
}, allowedTools: readonly string[]): ToolEvidenceItem;
|
|
299
|
+
export declare const reportHash: z.ZodString;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { AnalysisPolicySchema, AtomicAmountSchema, contentHash, matchesTemplateInput, ModelUsageSchema, ObjectSchemaDefinition, ResearchAnalysisSchema, WorkflowNodeSchema } from './index.js';
|
|
3
|
+
import { ACTIVITY_READ_METHODS, ActivityEvidenceIdSchema } from './indexed-activity.js';
|
|
4
|
+
import { ToolEvidenceItemSchema } from './workflow.js';
|
|
5
|
+
/**
|
|
6
|
+
* Shared manifest and report rules for the indexed first-party agents (P02 Deployer Investigator, P03 Wallet Analyst). Their manifests use
|
|
7
|
+
* their own strict schema (like the Solana inspector), so `AgentManifestSchema` and every stored manifest hash stay unchanged. Every run is
|
|
8
|
+
* bounded by the paid RPC ceiling of 16 metered calls, pins one latest block (sequencer-confirmed) and rechecks it at completion.
|
|
9
|
+
*/
|
|
10
|
+
export const INDEXED_AGENT_CHAINS = ['ethereum', 'base'];
|
|
11
|
+
export const IndexedAgentChainSchema = z.enum(INDEXED_AGENT_CHAINS);
|
|
12
|
+
export const INDEXED_AGENT_RPC_CEILING = 16;
|
|
13
|
+
export const Hex32Schema = z.string().regex(/^0x[a-fA-F0-9]{64}$/, 'Expected a 32-byte hex hash');
|
|
14
|
+
export const BlockNumberInputSchema = z.string().regex(/^(0|[1-9][0-9]{0,15})$/, 'Expected a decimal block number');
|
|
15
|
+
const Identifier = z.string().regex(/^[a-z][a-z0-9._-]{0,63}$/);
|
|
16
|
+
const Semver = z.string().regex(/^\d+\.\d+\.\d+$/);
|
|
17
|
+
const Hash = z.string().regex(/^[a-f0-9]{64}$/);
|
|
18
|
+
export function indexedManifestSchema(outputSchemaId) {
|
|
19
|
+
return z.strictObject({
|
|
20
|
+
schemaVersion: z.literal('1.0'), id: Identifier, version: Semver, name: z.string().min(1).max(100), description: z.string().min(1).max(2000),
|
|
21
|
+
author: z.strictObject({ id: Identifier, name: z.string().min(1).max(100), ownership: z.enum(['first-party', 'independent']) }),
|
|
22
|
+
license: z.string().min(1).max(100), visibility: z.enum(['private', 'source-visible', 'source-private']),
|
|
23
|
+
chains: z.array(IndexedAgentChainSchema).min(1).max(INDEXED_AGENT_CHAINS.length), inputSchema: ObjectSchemaDefinition, outputSchemaId: z.literal(outputSchemaId),
|
|
24
|
+
tools: z.array(z.strictObject({ id: Identifier, version: Semver, capability: z.literal('evm.read'), chains: z.array(IndexedAgentChainSchema).min(1).max(INDEXED_AGENT_CHAINS.length), addressScope: z.literal('input-address'), maximumCalls: z.number().int().min(1).max(INDEXED_AGENT_RPC_CEILING) })).min(1).max(4),
|
|
25
|
+
modelPolicy: z.strictObject({ mode: z.literal('deterministic'), maximumModelTokens: z.literal(0) }),
|
|
26
|
+
// Optional bounded AI-assisted summary, identical in shape and pricing to the Token Researcher's policy.analysis.
|
|
27
|
+
policy: z.strictObject({ analysis: AnalysisPolicySchema }).optional(),
|
|
28
|
+
limits: z.strictObject({ maximumRpcCalls: z.number().int().min(1).max(INDEXED_AGENT_RPC_CEILING), maximumDurationMs: z.number().int().min(1000).max(120000), maximumOutputBytes: z.number().int().min(1024).max(262144), maximumGraphDepth: z.number().int().min(1).max(16), maximumPages: z.number().int().min(0).max(2), maximumExecutionAtomic: AtomicAmountSchema }),
|
|
29
|
+
workflow: z.array(WorkflowNodeSchema).min(3).max(32), testCases: z.array(Identifier).min(1).max(100),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/** Executable subset: the fixed graph, the template's tool references and input declaration, and a run budget that fits the minimum plan. */
|
|
33
|
+
export function indexedManifestIssues(manifest, template, minimumRpcCalls) {
|
|
34
|
+
const issues = [];
|
|
35
|
+
if (new Set(manifest.chains).size !== manifest.chains.length)
|
|
36
|
+
issues.push({ path: ['chains'], message: 'Duplicate chain' });
|
|
37
|
+
if (contentHash(manifest.workflow) !== contentHash(template.workflow))
|
|
38
|
+
issues.push({ path: ['workflow'], message: `The executor supports only the bounded ${template.name} graph.` });
|
|
39
|
+
if (!matchesTemplateInput(manifest, [template]))
|
|
40
|
+
issues.push({ path: ['inputSchema'], message: `The input declaration must match the supported ${template.name} inputs with the selected chains.` });
|
|
41
|
+
const refs = (value) => value.tools.map((tool) => `${tool.id}@${tool.version}`).join(',');
|
|
42
|
+
if (refs(manifest) !== refs(template))
|
|
43
|
+
issues.push({ path: ['tools'], message: `Only ${refs(template)} with the read-only input-address grant are executable.` });
|
|
44
|
+
for (const [index, tool] of manifest.tools.entries()) {
|
|
45
|
+
if (!manifest.chains.every((chain) => tool.chains.includes(chain)))
|
|
46
|
+
issues.push({ path: ['tools', index, 'chains'], message: `Tool ${tool.id} cannot execute on every declared chain` });
|
|
47
|
+
if (tool.maximumCalls > manifest.limits.maximumRpcCalls)
|
|
48
|
+
issues.push({ path: ['tools', index, 'maximumCalls'], message: `Tool ${tool.id} exceeds the run call budget` });
|
|
49
|
+
}
|
|
50
|
+
if (manifest.limits.maximumRpcCalls < minimumRpcCalls)
|
|
51
|
+
issues.push({ path: ['limits', 'maximumRpcCalls'], message: `${template.name} needs at least ${minimumRpcCalls} RPC calls.` });
|
|
52
|
+
return issues;
|
|
53
|
+
}
|
|
54
|
+
export const IndexedSnapshotSchema = z.strictObject({ blockNumber: AtomicAmountSchema, blockHash: Hex32Schema, timestamp: AtomicAmountSchema, finality: z.literal('sequencer-confirmed'), canonicality: z.enum(['verified-at-completion', 'unchecked', 'changed']) });
|
|
55
|
+
export const IndexedReportErrorSchema = z.strictObject({ category: z.string().regex(/^[a-z][a-z-]{1,63}$/), message: z.string().max(1000), step: z.string().max(64), evidenceId: ActivityEvidenceIdSchema.optional() });
|
|
56
|
+
export const IndexedUsageSchema = z.strictObject({ rpcCalls: z.number().int().nonnegative(), maximumRpcCalls: z.number().int().positive().max(INDEXED_AGENT_RPC_CEILING), elapsedMs: z.number().int().nonnegative(), modelTokens: z.literal(0), providerCostAtomic: z.null(), providerCostStatus: z.literal('unpriced'), model: ModelUsageSchema.optional() });
|
|
57
|
+
export const IndexedEvidenceSchema = z.array(ToolEvidenceItemSchema).max(INDEXED_AGENT_RPC_CEILING * 2);
|
|
58
|
+
export { ResearchAnalysisSchema as IndexedAnalysisSchema };
|
|
59
|
+
export const NotComputedSchema = z.strictObject({ status: z.literal('not-computed'), reason: z.string().min(1).max(600), sourceGap: z.enum(['historical-prices', 'trade-classification', 'transaction-fees']) });
|
|
60
|
+
/** Every `evidenceIds` array and `evidenceId` string outside the evidence list, bounded against hostile nesting. */
|
|
61
|
+
function references(value) {
|
|
62
|
+
const found = [];
|
|
63
|
+
const stack = [{ node: value, depth: 0 }];
|
|
64
|
+
let visited = 0;
|
|
65
|
+
while (stack.length && visited++ < 50000) {
|
|
66
|
+
const { node, depth } = stack.pop();
|
|
67
|
+
if (Array.isArray(node)) {
|
|
68
|
+
for (const child of node)
|
|
69
|
+
stack.push({ node: child, depth: depth + 1 });
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (!node || typeof node !== 'object' || depth > 32)
|
|
73
|
+
continue;
|
|
74
|
+
for (const [key, child] of Object.entries(node)) {
|
|
75
|
+
if (key === 'evidence' && depth === 0)
|
|
76
|
+
continue;
|
|
77
|
+
if (key === 'evidenceIds' && Array.isArray(child))
|
|
78
|
+
found.push(...child.map(String));
|
|
79
|
+
else if (key === 'evidenceId' && typeof child === 'string')
|
|
80
|
+
found.push(child);
|
|
81
|
+
else
|
|
82
|
+
stack.push({ node: child, depth: depth + 1 });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return found;
|
|
86
|
+
}
|
|
87
|
+
/** Envelope, provenance, budget and AI-summary rules shared by both report schemas. */
|
|
88
|
+
export function indexedReportIssues(report, allowedTools, ctx) {
|
|
89
|
+
const issue = (message, path = []) => ctx.addIssue({ code: 'custom', message, path });
|
|
90
|
+
const ids = new Set(report.evidence.map((item) => item.id));
|
|
91
|
+
if (ids.size !== report.evidence.length)
|
|
92
|
+
issue('Duplicate evidence id');
|
|
93
|
+
for (const item of report.evidence) {
|
|
94
|
+
if (!allowedTools.includes(item.tool) || item.capability !== 'evm.read')
|
|
95
|
+
issue(`Evidence ${item.id} was not produced by a declared tool.`);
|
|
96
|
+
if (!ACTIVITY_READ_METHODS.includes(item.source.method))
|
|
97
|
+
issue(`Unsupported read method ${item.source.method}`);
|
|
98
|
+
if (item.chain !== report.input.chain)
|
|
99
|
+
issue(`Evidence ${item.id} belongs to another chain.`);
|
|
100
|
+
}
|
|
101
|
+
for (const id of references(report))
|
|
102
|
+
if (!ids.has(id))
|
|
103
|
+
issue(`Unknown evidence reference ${id}`);
|
|
104
|
+
if (report.usage.rpcCalls > report.usage.maximumRpcCalls || report.evidence.length > report.usage.rpcCalls)
|
|
105
|
+
issue('RPC usage or evidence count exceeds the recorded budget.', ['usage']);
|
|
106
|
+
if (report.status !== 'failed' && report.snapshot?.canonicality !== 'verified-at-completion')
|
|
107
|
+
issue('Only a report whose pinned block was rechecked as canonical can be complete or partial.', ['status']);
|
|
108
|
+
if ((report.analysis === undefined) !== (report.usage.model === undefined))
|
|
109
|
+
issue('An AI-assisted summary section and usage.model must be reported together.', ['analysis']);
|
|
110
|
+
if (report.analysis) {
|
|
111
|
+
const completed = report.analysis.status === 'completed';
|
|
112
|
+
if (completed === (report.analysis.unavailableReason !== undefined))
|
|
113
|
+
issue('Only a summary that did not complete states an unavailable or skipped reason.', ['analysis', 'unavailableReason']);
|
|
114
|
+
if (!completed && report.analysis.findings.length)
|
|
115
|
+
issue('Only a completed AI-assisted summary can contain findings.', ['analysis', 'findings']);
|
|
116
|
+
if (report.analysis.status === 'skipped' && report.usage.model && (report.usage.model.inputTokens || report.usage.model.outputTokens || report.usage.model.costMicrousd))
|
|
117
|
+
issue('A skipped AI-assisted summary records no model usage.', ['usage', 'model']);
|
|
118
|
+
if (report.usage.model?.costStatus === 'unresolved' && (report.analysis.status !== 'unavailable' || report.analysis.findings.length || report.usage.model.inputTokens || report.usage.model.outputTokens || report.usage.model.costMicrousd < 1))
|
|
119
|
+
issue('An unresolved model cost belongs to an unavailable summary without findings and states its reserved maximum, never zero.', ['usage', 'model', 'costStatus']);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/** Checkpoint receipt scope for indexed agents: a declared tool, the read-method allowlist, the accepted chain and an intact envelope. */
|
|
123
|
+
export function validateIndexedReceipt(evidence, input, allowedTools) {
|
|
124
|
+
const receipt = ToolEvidenceItemSchema.parse(evidence);
|
|
125
|
+
const chainId = input.chain === 'ethereum' ? 1 : input.chain === 'base' ? 8453 : null;
|
|
126
|
+
if (!allowedTools.includes(receipt.tool) || receipt.capability !== 'evm.read' || !ACTIVITY_READ_METHODS.includes(receipt.source.method) || receipt.chain !== input.chain
|
|
127
|
+
|| (receipt.snapshot !== null && (receipt.snapshot.kind !== 'evm-block' || receipt.snapshot.chainId !== chainId)))
|
|
128
|
+
throw new Error('Receipt is outside the indexed agent read scope.');
|
|
129
|
+
return receipt;
|
|
130
|
+
}
|
|
131
|
+
export const reportHash = Hash;
|