sakura-agent 0.1.0 → 0.1.1
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 +144 -78
- package/README.zh-CN.md +145 -79
- package/THIRD_PARTY_NOTICES.md +8 -58
- package/dist/packages/agent/src/index.d.ts +49 -11
- package/dist/packages/agent/src/index.js +50 -55
- package/dist/packages/agent/src/restrict-tools.d.ts +6 -0
- package/dist/packages/agent/src/restrict-tools.js +11 -0
- package/dist/packages/agent/src/system-prompt.d.ts +5 -0
- package/dist/packages/agent/src/system-prompt.js +1 -1
- package/dist/packages/agent/src/wake.d.ts +41 -0
- package/dist/packages/agent/src/wake.js +71 -0
- package/dist/packages/env/src/confine.d.ts +13 -0
- package/dist/packages/env/src/confine.js +40 -0
- package/dist/packages/env/src/connect-ssh.d.ts +33 -0
- package/dist/packages/env/src/connect-ssh.js +132 -0
- package/dist/packages/env/src/index.d.ts +5 -1
- package/dist/packages/env/src/index.js +3 -1
- package/dist/packages/env/src/local.d.ts +11 -2
- package/dist/packages/env/src/local.js +42 -10
- package/dist/packages/env/src/remote.d.ts +17 -1
- package/dist/packages/env/src/remote.js +54 -4
- package/dist/packages/evals/src/bfcl.d.ts +24 -0
- package/dist/packages/evals/src/bfcl.js +71 -0
- package/dist/packages/evals/src/index.d.ts +3 -0
- package/dist/packages/evals/src/index.js +2 -0
- package/dist/packages/evals/src/png.d.ts +2 -0
- package/dist/packages/evals/src/png.js +30 -0
- package/dist/packages/evals/src/pool.d.ts +3 -0
- package/dist/packages/evals/src/pool.js +22 -0
- package/dist/packages/evals/src/providers.d.ts +13 -0
- package/dist/packages/evals/src/providers.js +23 -0
- package/dist/packages/kernel/src/compaction.d.ts +19 -0
- package/dist/packages/kernel/src/compaction.js +12 -2
- package/dist/packages/kernel/src/goal.d.ts +10 -1
- package/dist/packages/kernel/src/goal.js +28 -0
- package/dist/packages/kernel/src/hooks.d.ts +5 -0
- package/dist/packages/kernel/src/hooks.js +21 -1
- package/dist/packages/kernel/src/index.d.ts +3 -2
- package/dist/packages/kernel/src/index.js +1 -0
- package/dist/packages/kernel/src/loop.d.ts +28 -4
- package/dist/packages/kernel/src/loop.js +69 -47
- package/dist/packages/kernel/src/types.d.ts +25 -4
- package/dist/packages/kernel/src/usage.d.ts +3 -0
- package/dist/packages/kernel/src/usage.js +16 -0
- package/dist/packages/llm/src/chat/request.js +22 -4
- package/dist/packages/llm/src/chat/retry.d.ts +1 -1
- package/dist/packages/llm/src/chat/retry.js +1 -1
- package/dist/packages/llm/src/index.js +7 -2
- package/dist/packages/plugins/context/src/index.d.ts +2 -1
- package/dist/packages/plugins/context/src/index.js +2 -1
- package/dist/packages/plugins/limits/src/index.d.ts +4 -1
- package/dist/packages/plugins/redaction/src/index.d.ts +3 -0
- package/dist/packages/plugins/redaction/src/index.js +3 -0
- package/dist/packages/plugins/redaction/src/rules.gen.js +1 -1
- package/dist/packages/plugins/review/src/chain.d.ts +2 -0
- package/dist/packages/plugins/review/src/chain.js +2 -1
- package/dist/packages/plugins/review/src/hard-rules.d.ts +6 -0
- package/dist/packages/plugins/review/src/hard-rules.js +58 -25
- package/dist/packages/plugins/review/src/index.d.ts +13 -0
- package/dist/packages/plugins/review/src/index.js +9 -5
- package/dist/packages/plugins/tools/src/builtin/bash.js +24 -10
- package/dist/packages/plugins/toolset/src/codemode.d.ts +17 -6
- package/dist/packages/plugins/toolset/src/codemode.js +84 -26
- package/dist/packages/plugins/toolset/src/index.d.ts +1 -1
- package/dist/packages/plugins/toolset/src/index.js +1 -1
- package/dist/packages/plugins/trace/src/index.d.ts +27 -0
- package/dist/packages/plugins/trace/src/index.js +29 -0
- package/dist/packages/plugins/trace/src/modules.d.ts +6 -0
- package/dist/packages/plugins/trace/src/modules.js +28 -0
- package/dist/packages/session/src/file-log.d.ts +6 -1
- package/dist/packages/session/src/file-log.js +45 -25
- package/dist/packages/session/src/fork.d.ts +16 -0
- package/dist/packages/session/src/fork.js +70 -0
- package/dist/packages/session/src/index.d.ts +2 -0
- package/dist/packages/session/src/index.js +1 -0
- package/dist/packages/session/src/log-core.d.ts +37 -0
- package/dist/packages/session/src/log-core.js +47 -0
- package/dist/packages/session/src/memory-log.d.ts +3 -12
- package/dist/packages/session/src/memory-log.js +3 -23
- package/dist/packages/session/src/projection.js +2 -0
- package/dist/packages/testing/src/faux.d.ts +36 -0
- package/dist/packages/testing/src/faux.js +69 -0
- package/dist/packages/testing/src/index.d.ts +4 -0
- package/dist/packages/testing/src/index.js +2 -0
- package/dist/packages/testing/src/rng.d.ts +7 -0
- package/dist/packages/testing/src/rng.js +17 -0
- package/dist/sdk/index.d.ts +11 -3
- package/dist/sdk/index.js +5 -1
- package/dist/sdk/testing.d.ts +2 -0
- package/dist/sdk/testing.js +2 -0
- package/package.json +5 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { projectMessages } from "./projection.js";
|
|
3
|
+
/**
|
|
4
|
+
* The one implementation of "a log": entries in a tree, one leaf, appends in order. The log is only as durable as its storage, and a log and its
|
|
5
|
+
* storage never disagree: an entry joins the tree after it is saved, and an append that fails changes nothing and does not stop the ones after it.
|
|
6
|
+
*/
|
|
7
|
+
export function createLog(tree, storage, options = {}) {
|
|
8
|
+
const now = options.now ?? Date.now;
|
|
9
|
+
const newId = options.newId ?? (() => randomUUID().slice(0, 8));
|
|
10
|
+
// Appends run one after another, each starting from where the one before ended. A failed one is reported to its caller and not to the next.
|
|
11
|
+
let queue = Promise.resolve();
|
|
12
|
+
return {
|
|
13
|
+
/** Resolves when everything started so far has been saved or has failed. */
|
|
14
|
+
settled: () => queue.then(() => undefined, () => undefined),
|
|
15
|
+
append(body) {
|
|
16
|
+
const run = queue.then(async () => {
|
|
17
|
+
const entry = { ...body, id: newId(), parentId: tree.leaf(), ts: now() };
|
|
18
|
+
await storage.saveEntry(entry);
|
|
19
|
+
tree.add(entry);
|
|
20
|
+
return entry;
|
|
21
|
+
});
|
|
22
|
+
queue = run.catch(() => undefined);
|
|
23
|
+
return run;
|
|
24
|
+
},
|
|
25
|
+
async branch() {
|
|
26
|
+
return tree.branch();
|
|
27
|
+
},
|
|
28
|
+
async project(upTo) {
|
|
29
|
+
const branch = tree.branch();
|
|
30
|
+
return projectMessages(upTo === undefined
|
|
31
|
+
? branch
|
|
32
|
+
: branch.slice(0, Math.max(0, branch.findIndex((entry) => entry.id === upTo))));
|
|
33
|
+
},
|
|
34
|
+
/**
|
|
35
|
+
* Takes effect at once. Entries that were already waiting to be saved follow the new end, so do not rewind while appends are in flight
|
|
36
|
+
* (the kernel does not: one run at a time, and it waits for each append).
|
|
37
|
+
*/
|
|
38
|
+
rewindTo(entryId) {
|
|
39
|
+
const before = tree.leaf();
|
|
40
|
+
tree.moveLeaf(entryId);
|
|
41
|
+
if (entryId === before)
|
|
42
|
+
return;
|
|
43
|
+
queue = queue.then(() => storage.saveRewind(entryId)).catch(() => undefined);
|
|
44
|
+
},
|
|
45
|
+
leaf: () => tree.leaf(),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
newId?: () => string;
|
|
5
|
-
}
|
|
6
|
-
/** A session log that can go back to an earlier entry and carry on from there. */
|
|
7
|
-
export interface RewindableLog extends Log {
|
|
8
|
-
/** Moves the end of the conversation back to an earlier entry (or to the very start with null). Later entries start a new branch. */
|
|
9
|
-
rewindTo(entryId: string | null): void;
|
|
10
|
-
/** Id of the entry the next one will follow. */
|
|
11
|
-
leaf(): string | null;
|
|
12
|
-
}
|
|
1
|
+
import type { LogEntry } from "../../kernel/src/index.js";
|
|
2
|
+
import type { LogOptions, RewindableLog } from "./log-core.js";
|
|
3
|
+
export type { LogOptions, RewindableLog } from "./log-core.js";
|
|
13
4
|
/** A log that lives only in memory (or wraps entries that were loaded elsewhere). */
|
|
14
5
|
export declare function createMemoryLog(options?: LogOptions & {
|
|
15
6
|
entries?: readonly LogEntry[];
|
|
@@ -1,27 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { projectMessages } from "./projection.js";
|
|
1
|
+
import { createLog } from "./log-core.js";
|
|
3
2
|
import { createTree } from "./tree.js";
|
|
4
3
|
/** A log that lives only in memory (or wraps entries that were loaded elsewhere). */
|
|
5
4
|
export function createMemoryLog(options = {}) {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
const tree = createTree(options.entries ?? []);
|
|
9
|
-
return {
|
|
10
|
-
async append(body) {
|
|
11
|
-
const entry = { ...body, id: newId(), parentId: tree.leaf(), ts: now() };
|
|
12
|
-
tree.add(entry);
|
|
13
|
-
return entry;
|
|
14
|
-
},
|
|
15
|
-
async branch() {
|
|
16
|
-
return tree.branch();
|
|
17
|
-
},
|
|
18
|
-
async project(upTo) {
|
|
19
|
-
const branch = tree.branch();
|
|
20
|
-
return projectMessages(upTo === undefined
|
|
21
|
-
? branch
|
|
22
|
-
: branch.slice(0, Math.max(0, branch.findIndex((entry) => entry.id === upTo))));
|
|
23
|
-
},
|
|
24
|
-
rewindTo: (entryId) => tree.moveLeaf(entryId),
|
|
25
|
-
leaf: () => tree.leaf(),
|
|
26
|
-
};
|
|
5
|
+
const { settled: _settled, ...log } = createLog(createTree(options.entries ?? []), { saveEntry: async () => undefined, saveRewind: async () => undefined }, options);
|
|
6
|
+
return log;
|
|
27
7
|
}
|
|
@@ -64,6 +64,8 @@ export function projectMessages(branch) {
|
|
|
64
64
|
const entry = branch[index];
|
|
65
65
|
if (entry?.type !== "custom_message" || !entry.pinned)
|
|
66
66
|
continue;
|
|
67
|
+
if (edits.get(entry.id) === null)
|
|
68
|
+
continue; // a pinned message can be withdrawn too (an earlier goal)
|
|
67
69
|
const message = entryToMessage(entry);
|
|
68
70
|
if (message)
|
|
69
71
|
messages.push(message);
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { LlmClient, LlmRequest, ProviderError, StopReason, Usage } from "../../kernel/src/index.js";
|
|
2
|
+
export interface FauxTurn {
|
|
3
|
+
text?: string;
|
|
4
|
+
reasoning?: string;
|
|
5
|
+
toolCalls?: Array<{
|
|
6
|
+
name: string;
|
|
7
|
+
args: unknown;
|
|
8
|
+
id?: string;
|
|
9
|
+
}>;
|
|
10
|
+
/** Cut the output off in the middle of this tool call (finish_reason "length"). */
|
|
11
|
+
truncatedToolCall?: {
|
|
12
|
+
name: string;
|
|
13
|
+
id?: string;
|
|
14
|
+
};
|
|
15
|
+
usage?: Partial<Usage>;
|
|
16
|
+
stop?: StopReason;
|
|
17
|
+
/** Fail the request instead of answering. */
|
|
18
|
+
error?: ProviderError;
|
|
19
|
+
/** Never answer; wait until the request is aborted. */
|
|
20
|
+
hang?: boolean;
|
|
21
|
+
/** Send this text, then a restart (as an adapter does after a dropped connection), then the real reply. */
|
|
22
|
+
droppedFirst?: string;
|
|
23
|
+
/** Split text into pieces of this many characters (default: one piece). */
|
|
24
|
+
chunkSize?: number;
|
|
25
|
+
}
|
|
26
|
+
export type FauxScript = FauxTurn[] | ((request: LlmRequest, index: number) => FauxTurn);
|
|
27
|
+
export interface FauxClient extends LlmClient {
|
|
28
|
+
/** Every request received, in order. */
|
|
29
|
+
requests: LlmRequest[];
|
|
30
|
+
}
|
|
31
|
+
export interface FauxOptions {
|
|
32
|
+
contextWindow?: number;
|
|
33
|
+
supportsImages?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** A scripted stand-in for a model: replays the given turns, one per request. */
|
|
36
|
+
export declare function createFauxClient(script: FauxScript, options?: FauxOptions): FauxClient;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
function abortError() {
|
|
2
|
+
const error = new Error("aborted");
|
|
3
|
+
error.name = "AbortError";
|
|
4
|
+
return error;
|
|
5
|
+
}
|
|
6
|
+
function waitForAbort(signal) {
|
|
7
|
+
return new Promise((_, reject) => {
|
|
8
|
+
if (signal.aborted)
|
|
9
|
+
reject(abortError());
|
|
10
|
+
signal.addEventListener("abort", () => reject(abortError()), { once: true });
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function estimateTokens(value) {
|
|
14
|
+
return Math.ceil(JSON.stringify(value).length / 4);
|
|
15
|
+
}
|
|
16
|
+
function* pieces(value, size) {
|
|
17
|
+
if (!size || size >= value.length) {
|
|
18
|
+
yield value;
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
for (let start = 0; start < value.length; start += size)
|
|
22
|
+
yield value.slice(start, start + size);
|
|
23
|
+
}
|
|
24
|
+
/** A scripted stand-in for a model: replays the given turns, one per request. */
|
|
25
|
+
export function createFauxClient(script, options = {}) {
|
|
26
|
+
const requests = [];
|
|
27
|
+
let callCount = 0;
|
|
28
|
+
return {
|
|
29
|
+
requests,
|
|
30
|
+
model: { id: "faux", contextWindow: options.contextWindow ?? 100_000, supportsImages: options.supportsImages ?? true },
|
|
31
|
+
async *stream(request, signal) {
|
|
32
|
+
requests.push(request);
|
|
33
|
+
const index = callCount++;
|
|
34
|
+
const turn = typeof script === "function" ? script(request, index) : script[index];
|
|
35
|
+
if (!turn)
|
|
36
|
+
throw new Error(`faux script has no turn for request ${index + 1}`);
|
|
37
|
+
if (signal.aborted)
|
|
38
|
+
throw abortError();
|
|
39
|
+
if (turn.error)
|
|
40
|
+
throw turn.error;
|
|
41
|
+
if (turn.hang)
|
|
42
|
+
await waitForAbort(signal);
|
|
43
|
+
if (turn.droppedFirst) {
|
|
44
|
+
yield { type: "text_delta", delta: turn.droppedFirst };
|
|
45
|
+
yield { type: "restart" };
|
|
46
|
+
}
|
|
47
|
+
if (turn.reasoning)
|
|
48
|
+
yield { type: "reasoning_delta", delta: turn.reasoning };
|
|
49
|
+
if (turn.text)
|
|
50
|
+
for (const piece of pieces(turn.text, turn.chunkSize))
|
|
51
|
+
yield { type: "text_delta", delta: piece };
|
|
52
|
+
let toolCount = 0;
|
|
53
|
+
for (const call of turn.toolCalls ?? []) {
|
|
54
|
+
toolCount++;
|
|
55
|
+
yield { type: "tool_call", call: { id: call.id ?? `call_${index + 1}_${toolCount}`, name: call.name, args: call.args } };
|
|
56
|
+
}
|
|
57
|
+
if (turn.truncatedToolCall) {
|
|
58
|
+
yield { type: "tool_call_truncated", id: turn.truncatedToolCall.id ?? `call_${index + 1}_cut`, name: turn.truncatedToolCall.name };
|
|
59
|
+
}
|
|
60
|
+
const output = estimateTokens([turn.text, turn.reasoning, turn.toolCalls]);
|
|
61
|
+
yield {
|
|
62
|
+
type: "usage",
|
|
63
|
+
usage: { input: estimateTokens(request.messages), output, cacheRead: 0, cacheWrite: 0, ...turn.usage },
|
|
64
|
+
};
|
|
65
|
+
const stop = turn.stop ?? (turn.truncatedToolCall ? "length" : toolCount > 0 ? "tool_use" : "stop");
|
|
66
|
+
yield { type: "done", stop };
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Small seeded random generator (mulberry32) so generated test cases are reproducible.
|
|
2
|
+
export function createRng(seed) {
|
|
3
|
+
let state = seed >>> 0;
|
|
4
|
+
const next = () => {
|
|
5
|
+
state = (state + 0x6d2b79f5) >>> 0;
|
|
6
|
+
let t = state;
|
|
7
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
8
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
9
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
10
|
+
};
|
|
11
|
+
return {
|
|
12
|
+
next,
|
|
13
|
+
int: (min, max) => min + Math.floor(next() * (max - min + 1)),
|
|
14
|
+
pick: (items) => items[Math.floor(next() * items.length)],
|
|
15
|
+
chance: (probability) => next() < probability,
|
|
16
|
+
};
|
|
17
|
+
}
|
package/dist/sdk/index.d.ts
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
export { buildSystemPrompt, bundle, compose, CompositionError, corePlugins, createAgent } from "../packages/agent/src/index.js";
|
|
2
2
|
export type { Agent, AgentConfig, Composable, ModelConfig } from "../packages/agent/src/index.js";
|
|
3
|
-
export { createLocalEnvironment, createRemoteEnvironment } from "../packages/env/src/index.js";
|
|
4
|
-
export type { RemoteRunner } from "../packages/env/src/index.js";
|
|
5
|
-
export type { Content, Environment, Event, LlmClient, Plugin, RunHandle, RunResult, Tool, ToolContext, ToolResult } from "../packages/kernel/src/index.js";
|
|
3
|
+
export { createLocalEnvironment, createRemoteEnvironment, createSshEnvironment, OutsideDirectoryError, RemoteConnectionError } from "../packages/env/src/index.js";
|
|
4
|
+
export type { LocalOptions, RemoteRunner, SshOptions } from "../packages/env/src/index.js";
|
|
5
|
+
export type { CompactionConfig, Content, ContextStatus, Decision, EntryBody, Environment, Event, EventTransform, ExecResult, FileInfo, GoalRecord, GoalStatus, HookContext, HookName, Hooks, LlmClient, LlmEvent, LlmRequest, Log, LogEntry, Message, ModelInfo, PauseReason, Plugin, PluginApi, PrepareContext, ProcessHandle, Prompts, ProviderErrorKind, Role, RunEndReason, RunHandle, RunOptions, RunResult, StopReason, ThinkingLevel, Tool, ToolCall, ToolContext, ToolDecl, ToolEffect, ToolResult, TurnInfo, Usage, UsageTotals, UserInput, } from "../packages/kernel/src/index.js";
|
|
6
|
+
export { FatalHookError, ProviderError } from "../packages/kernel/src/index.js";
|
|
6
7
|
export { compatPresets, createChatClient } from "../packages/llm/src/index.js";
|
|
7
8
|
export type { ChatClientOptions, ChatCompat } from "../packages/llm/src/index.js";
|
|
9
|
+
export { contextPlugin } from "../packages/plugins/context/src/index.js";
|
|
10
|
+
export type { ContextOptions, ContextPlugin } from "../packages/plugins/context/src/index.js";
|
|
8
11
|
export { limitsPlugin } from "../packages/plugins/limits/src/index.js";
|
|
12
|
+
export { resiliencePlugin } from "../packages/plugins/resilience/src/index.js";
|
|
13
|
+
export type { FixOptions, ResilienceOptions } from "../packages/plugins/resilience/src/index.js";
|
|
9
14
|
export { redactionPlugin } from "../packages/plugins/redaction/src/index.js";
|
|
10
15
|
export { reviewPlugin } from "../packages/plugins/review/src/index.js";
|
|
16
|
+
export type { McpServerConfig, McpServerStatus } from "../packages/plugins/toolset/src/index.js";
|
|
17
|
+
export { toolsPlugin } from "../packages/plugins/tools/src/index.js";
|
|
18
|
+
export type { ToolsPluginOptions } from "../packages/plugins/tools/src/index.js";
|
package/dist/sdk/index.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export { buildSystemPrompt, bundle, compose, CompositionError, corePlugins, createAgent } from "../packages/agent/src/index.js";
|
|
2
|
-
export { createLocalEnvironment, createRemoteEnvironment } from "../packages/env/src/index.js";
|
|
2
|
+
export { createLocalEnvironment, createRemoteEnvironment, createSshEnvironment, OutsideDirectoryError, RemoteConnectionError } from "../packages/env/src/index.js";
|
|
3
|
+
export { FatalHookError, ProviderError } from "../packages/kernel/src/index.js";
|
|
3
4
|
export { compatPresets, createChatClient } from "../packages/llm/src/index.js";
|
|
5
|
+
export { contextPlugin } from "../packages/plugins/context/src/index.js";
|
|
4
6
|
export { limitsPlugin } from "../packages/plugins/limits/src/index.js";
|
|
7
|
+
export { resiliencePlugin } from "../packages/plugins/resilience/src/index.js";
|
|
5
8
|
export { redactionPlugin } from "../packages/plugins/redaction/src/index.js";
|
|
6
9
|
export { reviewPlugin } from "../packages/plugins/review/src/index.js";
|
|
10
|
+
export { toolsPlugin } from "../packages/plugins/tools/src/index.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sakura-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"workspaces": [
|
|
@@ -55,6 +55,10 @@
|
|
|
55
55
|
".": {
|
|
56
56
|
"types": "./dist/sdk/index.d.ts",
|
|
57
57
|
"import": "./dist/sdk/index.js"
|
|
58
|
+
},
|
|
59
|
+
"./testing": {
|
|
60
|
+
"types": "./dist/sdk/testing.d.ts",
|
|
61
|
+
"import": "./dist/sdk/testing.js"
|
|
58
62
|
}
|
|
59
63
|
},
|
|
60
64
|
"types": "./dist/sdk/index.d.ts",
|