meridian-sdk 1.2.0 → 1.3.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 +18 -0
- package/README.md +1 -0
- package/dist/agents.d.ts +143 -8
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +141 -14
- package/dist/agents.js.map +1 -1
- package/dist/client.d.ts +35 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +45 -3
- package/dist/client.js.map +1 -1
- package/dist/conflict/types.d.ts +54 -0
- package/dist/conflict/types.d.ts.map +1 -0
- package/dist/conflict/types.js +9 -0
- package/dist/conflict/types.js.map +1 -0
- package/dist/crdt/rga.d.ts +20 -4
- package/dist/crdt/rga.d.ts.map +1 -1
- package/dist/crdt/rga.js +42 -6
- package/dist/crdt/rga.js.map +1 -1
- package/dist/crdt/tree.d.ts +128 -0
- package/dist/crdt/tree.d.ts.map +1 -0
- package/dist/crdt/tree.js +304 -0
- package/dist/crdt/tree.js.map +1 -0
- package/dist/index.d.ts +13 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -3
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts +63 -3
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +18 -1
- package/dist/schema.js.map +1 -1
- package/dist/sync/delta.d.ts +35 -0
- package/dist/sync/delta.d.ts.map +1 -1
- package/dist/sync/delta.js +4 -0
- package/dist/sync/delta.js.map +1 -1
- package/dist/undo/UndoManager.d.ts +74 -0
- package/dist/undo/UndoManager.d.ts.map +1 -0
- package/dist/undo/UndoManager.js +318 -0
- package/dist/undo/UndoManager.js.map +1 -0
- package/dist/undo/types.d.ts +63 -0
- package/dist/undo/types.d.ts.map +1 -0
- package/dist/undo/types.js +9 -0
- package/dist/undo/types.js.map +1 -0
- package/dist/utils/fractional.d.ts +78 -0
- package/dist/utils/fractional.d.ts.map +1 -0
- package/dist/utils/fractional.js +159 -0
- package/dist/utils/fractional.js.map +1 -0
- package/dist/validation/index.d.ts +107 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +123 -0
- package/dist/validation/index.js.map +1 -0
- package/package.json +1 -1
- package/src/agents.ts +224 -15
- package/src/client.ts +52 -3
- package/src/conflict/types.ts +60 -0
- package/src/crdt/rga.ts +46 -7
- package/src/crdt/tree.ts +367 -0
- package/src/index.ts +31 -1
- package/src/schema.ts +24 -1
- package/src/sync/delta.ts +30 -1
- package/src/undo/UndoManager.ts +369 -0
- package/src/undo/types.ts +74 -0
- package/src/utils/fractional.ts +166 -0
- package/src/validation/index.ts +137 -0
- package/test/conflict.test.ts +242 -0
- package/test/fractional.test.ts +127 -0
- package/test/undo.test.ts +272 -0
- package/test/validation.test.ts +137 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# meridian-sdk
|
|
2
2
|
|
|
3
|
+
## 1.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 48647ce: **meridian-sdk**: Add granular permissions V2 schema (`PermissionsV2`, `PermEntry`, `OpMask`), multi-provider AI agent adapters (`executeOpenAITool`, `executeGeminiTool`, `OpenAIToolCall`, `GeminiFunctionCall`), and fix ORSet delta sync to return real deltas based on VectorClock instead of full state.
|
|
8
|
+
|
|
9
|
+
**meridian-devtools**: Add colors for `rga` (orange) and `tree` (sky) CRDT types in the visualization panel.
|
|
10
|
+
|
|
11
|
+
**meridian-react**: Compatibility update for granular permissions V2 and ORSet delta sync improvements in meridian-sdk.
|
|
12
|
+
|
|
13
|
+
## 1.2.1
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- 3086c3d: feat(crdt): add TreeCRDT for hierarchical collaborative editing
|
|
18
|
+
|
|
19
|
+
Implements a convergent hierarchical tree CRDT based on Kleppmann et al. (2021). Supports addNode, moveNode, updateNode, and deleteNode operations with cycle detection, LWW value updates, and tombstone deletes. The `client.tree(id)` factory and `useTree()` React hook are now available.
|
|
20
|
+
|
|
3
21
|
## 1.2.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -96,6 +96,7 @@ await Effect.runPromise(
|
|
|
96
96
|
| `client.crdtmap(id)` | `CRDTMapHandle` | — |
|
|
97
97
|
| `client.awareness(key, schema?)` | `AwarenessHandle<T>` | Optional |
|
|
98
98
|
| `client.rga(id)` | `RGAHandle` | — |
|
|
99
|
+
| `client.tree(id)` | `TreeHandle` | — |
|
|
99
100
|
|
|
100
101
|
Without a schema, `T = unknown`. With a schema, incoming deltas are validated at runtime via `Schema.decodeUnknownSync`.
|
|
101
102
|
|
package/dist/agents.d.ts
CHANGED
|
@@ -1,18 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Meridian
|
|
2
|
+
* Meridian AI agent tool use helpers.
|
|
3
3
|
*
|
|
4
|
-
* Generates
|
|
4
|
+
* Generates provider-compatible tool definitions from a list of CRDT IDs
|
|
5
5
|
* and executes tool calls against a Meridian server via HTTP (no WebSocket).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* Supported providers:
|
|
8
|
+
* - Anthropic Claude — `getMeridianTools()` (default)
|
|
9
|
+
* - OpenAI GPT — `toOpenAITools(getMeridianTools(...))`
|
|
10
|
+
* - Google Gemini — `toGeminiTools(getMeridianTools(...))`
|
|
11
|
+
*
|
|
12
|
+
* Usage (Anthropic):
|
|
8
13
|
* ```ts
|
|
9
14
|
* import { getMeridianTools, executeMeridianTool } from "meridian-sdk";
|
|
10
15
|
*
|
|
11
|
-
* const tools = getMeridianTools(
|
|
16
|
+
* const tools = getMeridianTools(config, ["counter", "tasks"]);
|
|
17
|
+
* // Pass to Anthropic messages.create({ tools })
|
|
18
|
+
* const result = await executeMeridianTool(config, toolUseBlock);
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Usage (OpenAI):
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { getMeridianTools, toOpenAITools, executeOpenAITool } from "meridian-sdk";
|
|
24
|
+
*
|
|
25
|
+
* const tools = toOpenAITools(getMeridianTools(config, ["counter", "tasks"]));
|
|
26
|
+
* // Pass to openai.chat.completions.create({ tools })
|
|
27
|
+
* // For each tool_call in the response — pass directly, no wrapping:
|
|
28
|
+
* const result = await executeOpenAITool(config, call);
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* Usage (Gemini):
|
|
32
|
+
* ```ts
|
|
33
|
+
* import { getMeridianTools, toGeminiTools, executeGeminiTool } from "meridian-sdk";
|
|
12
34
|
*
|
|
13
|
-
*
|
|
14
|
-
* //
|
|
15
|
-
*
|
|
35
|
+
* const tools = toGeminiTools(getMeridianTools(config, ["counter", "tasks"]));
|
|
36
|
+
* // Pass to model.generateContent({ tools })
|
|
37
|
+
* // For each functionCall part — pass directly, no wrapping:
|
|
38
|
+
* const result = await executeGeminiTool(config, part.functionCall);
|
|
16
39
|
* ```
|
|
17
40
|
*/
|
|
18
41
|
export interface Tool {
|
|
@@ -27,12 +50,85 @@ export interface Tool {
|
|
|
27
50
|
required?: string[];
|
|
28
51
|
};
|
|
29
52
|
}
|
|
53
|
+
/** OpenAI-compatible tool definition (Chat Completions `tools` array entry). */
|
|
54
|
+
export interface OpenAITool {
|
|
55
|
+
type: "function";
|
|
56
|
+
function: {
|
|
57
|
+
name: string;
|
|
58
|
+
description: string;
|
|
59
|
+
parameters: {
|
|
60
|
+
type: "object";
|
|
61
|
+
properties: Record<string, {
|
|
62
|
+
type: string;
|
|
63
|
+
description: string;
|
|
64
|
+
}>;
|
|
65
|
+
required?: string[];
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Convert Meridian tools to OpenAI Chat Completions format.
|
|
71
|
+
*
|
|
72
|
+
* ```ts
|
|
73
|
+
* const tools = toOpenAITools(getMeridianTools(config, crdtIds));
|
|
74
|
+
* // openai.chat.completions.create({ tools })
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export declare function toOpenAITools(tools: Tool[]): OpenAITool[];
|
|
78
|
+
/** Gemini FunctionDeclaration (single entry inside a `Tool.functionDeclarations` array). */
|
|
79
|
+
export interface GeminiFunctionDeclaration {
|
|
80
|
+
name: string;
|
|
81
|
+
description: string;
|
|
82
|
+
parameters: {
|
|
83
|
+
type: "OBJECT";
|
|
84
|
+
properties: Record<string, {
|
|
85
|
+
type: string;
|
|
86
|
+
description: string;
|
|
87
|
+
}>;
|
|
88
|
+
required?: string[];
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/** Gemini `Tool` wrapper passed to `model.generateContent({ tools })`. */
|
|
92
|
+
export interface GeminiTool {
|
|
93
|
+
functionDeclarations: GeminiFunctionDeclaration[];
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Convert Meridian tools to Google Gemini format.
|
|
97
|
+
*
|
|
98
|
+
* ```ts
|
|
99
|
+
* const tools = toGeminiTools(getMeridianTools(config, crdtIds));
|
|
100
|
+
* // model.generateContent({ tools })
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export declare function toGeminiTools(tools: Tool[]): GeminiTool;
|
|
104
|
+
/** Anthropic tool_use block — matches `ContentBlock` from `@anthropic-ai/sdk`. */
|
|
30
105
|
export interface ToolUseBlock {
|
|
31
106
|
type: "tool_use";
|
|
32
107
|
id: string;
|
|
33
108
|
name: string;
|
|
34
109
|
input: Record<string, unknown>;
|
|
35
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* OpenAI tool call — structurally matches `ChatCompletionMessageToolCall`
|
|
113
|
+
* from the `openai` package. Pass directly from `response.choices[0].message.tool_calls`.
|
|
114
|
+
*/
|
|
115
|
+
export interface OpenAIToolCall {
|
|
116
|
+
id: string;
|
|
117
|
+
type: "function";
|
|
118
|
+
function: {
|
|
119
|
+
name: string;
|
|
120
|
+
/** JSON-encoded arguments string, as returned by the OpenAI API. */
|
|
121
|
+
arguments: string;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Gemini function call — structurally matches `FunctionCall` from
|
|
126
|
+
* `@google/generative-ai`. Pass directly from `part.functionCall`.
|
|
127
|
+
*/
|
|
128
|
+
export interface GeminiFunctionCall {
|
|
129
|
+
name: string;
|
|
130
|
+
args: Record<string, unknown>;
|
|
131
|
+
}
|
|
36
132
|
export interface MeridianAgentConfig {
|
|
37
133
|
/** HTTP base URL of the Meridian server (e.g. https://meridian.example.com) */
|
|
38
134
|
baseUrl: string;
|
|
@@ -52,9 +148,48 @@ export interface MeridianAgentConfig {
|
|
|
52
148
|
*/
|
|
53
149
|
export declare function getMeridianTools(config: MeridianAgentConfig, crdtIds: string[]): Tool[];
|
|
54
150
|
/**
|
|
55
|
-
* Execute a Meridian tool call returned by Claude
|
|
151
|
+
* Execute a Meridian tool call returned by **Anthropic Claude**.
|
|
56
152
|
*
|
|
57
153
|
* Returns a JSON string suitable for the `content` field of a `tool_result` block.
|
|
154
|
+
*
|
|
155
|
+
* ```ts
|
|
156
|
+
* for (const block of response.content) {
|
|
157
|
+
* if (block.type === "tool_use") {
|
|
158
|
+
* const result = await executeMeridianTool(config, block);
|
|
159
|
+
* toolResults.push({ type: "tool_result", tool_use_id: block.id, content: result });
|
|
160
|
+
* }
|
|
161
|
+
* }
|
|
162
|
+
* ```
|
|
58
163
|
*/
|
|
59
164
|
export declare function executeMeridianTool(config: MeridianAgentConfig, toolUse: ToolUseBlock): Promise<string>;
|
|
165
|
+
/**
|
|
166
|
+
* Execute a Meridian tool call returned by **OpenAI**.
|
|
167
|
+
*
|
|
168
|
+
* Pass `tool_call` directly from `response.choices[0].message.tool_calls` —
|
|
169
|
+
* no wrapping required. Returns a JSON string for the `tool` role message content.
|
|
170
|
+
*
|
|
171
|
+
* ```ts
|
|
172
|
+
* for (const call of response.choices[0].message.tool_calls ?? []) {
|
|
173
|
+
* const result = await executeOpenAITool(config, call);
|
|
174
|
+
* messages.push({ role: "tool", tool_call_id: call.id, content: result });
|
|
175
|
+
* }
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
export declare function executeOpenAITool(config: MeridianAgentConfig, toolCall: OpenAIToolCall): Promise<string>;
|
|
179
|
+
/**
|
|
180
|
+
* Execute a Meridian tool call returned by **Google Gemini**.
|
|
181
|
+
*
|
|
182
|
+
* Pass `part.functionCall` directly — no wrapping, no id hack required.
|
|
183
|
+
* Returns a JSON string for the `functionResponse` part content.
|
|
184
|
+
*
|
|
185
|
+
* ```ts
|
|
186
|
+
* for (const part of response.candidates?.[0].content.parts ?? []) {
|
|
187
|
+
* if (part.functionCall) {
|
|
188
|
+
* const result = await executeGeminiTool(config, part.functionCall);
|
|
189
|
+
* // pass result back as functionResponse part
|
|
190
|
+
* }
|
|
191
|
+
* }
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
export declare function executeGeminiTool(config: MeridianAgentConfig, functionCall: GeminiFunctionCall): Promise<string>;
|
|
60
195
|
//# sourceMappingURL=agents.d.ts.map
|
package/dist/agents.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"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"}
|
package/dist/agents.js
CHANGED
|
@@ -1,21 +1,87 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Meridian
|
|
2
|
+
* Meridian AI agent tool use helpers.
|
|
3
3
|
*
|
|
4
|
-
* Generates
|
|
4
|
+
* Generates provider-compatible tool definitions from a list of CRDT IDs
|
|
5
5
|
* and executes tool calls against a Meridian server via HTTP (no WebSocket).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* Supported providers:
|
|
8
|
+
* - Anthropic Claude — `getMeridianTools()` (default)
|
|
9
|
+
* - OpenAI GPT — `toOpenAITools(getMeridianTools(...))`
|
|
10
|
+
* - Google Gemini — `toGeminiTools(getMeridianTools(...))`
|
|
11
|
+
*
|
|
12
|
+
* Usage (Anthropic):
|
|
8
13
|
* ```ts
|
|
9
14
|
* import { getMeridianTools, executeMeridianTool } from "meridian-sdk";
|
|
10
15
|
*
|
|
11
|
-
* const tools = getMeridianTools(
|
|
16
|
+
* const tools = getMeridianTools(config, ["counter", "tasks"]);
|
|
17
|
+
* // Pass to Anthropic messages.create({ tools })
|
|
18
|
+
* const result = await executeMeridianTool(config, toolUseBlock);
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Usage (OpenAI):
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { getMeridianTools, toOpenAITools, executeOpenAITool } from "meridian-sdk";
|
|
24
|
+
*
|
|
25
|
+
* const tools = toOpenAITools(getMeridianTools(config, ["counter", "tasks"]));
|
|
26
|
+
* // Pass to openai.chat.completions.create({ tools })
|
|
27
|
+
* // For each tool_call in the response — pass directly, no wrapping:
|
|
28
|
+
* const result = await executeOpenAITool(config, call);
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* Usage (Gemini):
|
|
32
|
+
* ```ts
|
|
33
|
+
* import { getMeridianTools, toGeminiTools, executeGeminiTool } from "meridian-sdk";
|
|
12
34
|
*
|
|
13
|
-
*
|
|
14
|
-
* //
|
|
15
|
-
*
|
|
35
|
+
* const tools = toGeminiTools(getMeridianTools(config, ["counter", "tasks"]));
|
|
36
|
+
* // Pass to model.generateContent({ tools })
|
|
37
|
+
* // For each functionCall part — pass directly, no wrapping:
|
|
38
|
+
* const result = await executeGeminiTool(config, part.functionCall);
|
|
16
39
|
* ```
|
|
17
40
|
*/
|
|
18
41
|
import { encode, uuidToBytes } from "./codec.js";
|
|
42
|
+
/**
|
|
43
|
+
* Convert Meridian tools to OpenAI Chat Completions format.
|
|
44
|
+
*
|
|
45
|
+
* ```ts
|
|
46
|
+
* const tools = toOpenAITools(getMeridianTools(config, crdtIds));
|
|
47
|
+
* // openai.chat.completions.create({ tools })
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export function toOpenAITools(tools) {
|
|
51
|
+
return tools.map(t => ({
|
|
52
|
+
type: "function",
|
|
53
|
+
function: {
|
|
54
|
+
name: t.name,
|
|
55
|
+
description: t.description,
|
|
56
|
+
parameters: {
|
|
57
|
+
type: "object",
|
|
58
|
+
properties: t.input_schema.properties,
|
|
59
|
+
...(t.input_schema.required ? { required: t.input_schema.required } : {}),
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Convert Meridian tools to Google Gemini format.
|
|
66
|
+
*
|
|
67
|
+
* ```ts
|
|
68
|
+
* const tools = toGeminiTools(getMeridianTools(config, crdtIds));
|
|
69
|
+
* // model.generateContent({ tools })
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export function toGeminiTools(tools) {
|
|
73
|
+
return {
|
|
74
|
+
functionDeclarations: tools.map(t => ({
|
|
75
|
+
name: t.name,
|
|
76
|
+
description: t.description,
|
|
77
|
+
parameters: {
|
|
78
|
+
type: "OBJECT",
|
|
79
|
+
properties: t.input_schema.properties,
|
|
80
|
+
...(t.input_schema.required ? { required: t.input_schema.required } : {}),
|
|
81
|
+
},
|
|
82
|
+
})),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
19
85
|
/**
|
|
20
86
|
* Returns an Anthropic `Tool[]` array for the given CRDT IDs.
|
|
21
87
|
*
|
|
@@ -76,15 +142,15 @@ export function getMeridianTools(config, crdtIds) {
|
|
|
76
142
|
}
|
|
77
143
|
return tools;
|
|
78
144
|
}
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
// Shared dispatcher (private)
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
79
148
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* Returns a JSON string suitable for the `content` field of a `tool_result` block.
|
|
149
|
+
* Core dispatch logic — routes a (name, input) pair to the right HTTP operation.
|
|
150
|
+
* All provider-specific executors delegate here.
|
|
83
151
|
*/
|
|
84
|
-
|
|
152
|
+
async function dispatchTool(config, name, input) {
|
|
85
153
|
const { baseUrl, token, namespace } = config;
|
|
86
|
-
const { name, input } = toolUse;
|
|
87
|
-
// Detect operation type and crdt_id from tool name
|
|
88
154
|
const readMatch = name.match(/^meridian_read_(.+)$/);
|
|
89
155
|
const incrementMatch = name.match(/^meridian_increment_(.+)$/);
|
|
90
156
|
const setMatch = name.match(/^meridian_set_(.+)$/);
|
|
@@ -115,7 +181,7 @@ export async function executeMeridianTool(config, toolUse) {
|
|
|
115
181
|
if (addMatch?.[1]) {
|
|
116
182
|
const crdtId = addMatch[1].replace(/_/g, "-");
|
|
117
183
|
// Always store as a string so useORSet<string> can read it back directly.
|
|
118
|
-
// If
|
|
184
|
+
// If the model passes a JSON object, re-serialize it to a stable string.
|
|
119
185
|
const rawEl = input.element;
|
|
120
186
|
const element = typeof rawEl === "string" ? rawEl : JSON.stringify(rawEl ?? null);
|
|
121
187
|
const clientId = Number(input.client_id ?? 1);
|
|
@@ -123,6 +189,67 @@ export async function executeMeridianTool(config, toolUse) {
|
|
|
123
189
|
}
|
|
124
190
|
return JSON.stringify({ error: `Unknown tool: ${name}` });
|
|
125
191
|
}
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
// Provider executors
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
/**
|
|
196
|
+
* Execute a Meridian tool call returned by **Anthropic Claude**.
|
|
197
|
+
*
|
|
198
|
+
* Returns a JSON string suitable for the `content` field of a `tool_result` block.
|
|
199
|
+
*
|
|
200
|
+
* ```ts
|
|
201
|
+
* for (const block of response.content) {
|
|
202
|
+
* if (block.type === "tool_use") {
|
|
203
|
+
* const result = await executeMeridianTool(config, block);
|
|
204
|
+
* toolResults.push({ type: "tool_result", tool_use_id: block.id, content: result });
|
|
205
|
+
* }
|
|
206
|
+
* }
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
export async function executeMeridianTool(config, toolUse) {
|
|
210
|
+
return dispatchTool(config, toolUse.name, toolUse.input);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Execute a Meridian tool call returned by **OpenAI**.
|
|
214
|
+
*
|
|
215
|
+
* Pass `tool_call` directly from `response.choices[0].message.tool_calls` —
|
|
216
|
+
* no wrapping required. Returns a JSON string for the `tool` role message content.
|
|
217
|
+
*
|
|
218
|
+
* ```ts
|
|
219
|
+
* for (const call of response.choices[0].message.tool_calls ?? []) {
|
|
220
|
+
* const result = await executeOpenAITool(config, call);
|
|
221
|
+
* messages.push({ role: "tool", tool_call_id: call.id, content: result });
|
|
222
|
+
* }
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
export async function executeOpenAITool(config, toolCall) {
|
|
226
|
+
let input;
|
|
227
|
+
try {
|
|
228
|
+
input = JSON.parse(toolCall.function.arguments);
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
return JSON.stringify({ error: "Failed to parse tool call arguments" });
|
|
232
|
+
}
|
|
233
|
+
return dispatchTool(config, toolCall.function.name, input);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Execute a Meridian tool call returned by **Google Gemini**.
|
|
237
|
+
*
|
|
238
|
+
* Pass `part.functionCall` directly — no wrapping, no id hack required.
|
|
239
|
+
* Returns a JSON string for the `functionResponse` part content.
|
|
240
|
+
*
|
|
241
|
+
* ```ts
|
|
242
|
+
* for (const part of response.candidates?.[0].content.parts ?? []) {
|
|
243
|
+
* if (part.functionCall) {
|
|
244
|
+
* const result = await executeGeminiTool(config, part.functionCall);
|
|
245
|
+
* // pass result back as functionResponse part
|
|
246
|
+
* }
|
|
247
|
+
* }
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
export async function executeGeminiTool(config, functionCall) {
|
|
251
|
+
return dispatchTool(config, functionCall.name, functionCall.args);
|
|
252
|
+
}
|
|
126
253
|
async function readCrdt(baseUrl, token, ns, id) {
|
|
127
254
|
const res = await fetch(`${baseUrl}/v1/namespaces/${ns}/crdts/${id}`, {
|
|
128
255
|
headers: { Authorization: `Bearer ${token}` },
|
package/dist/agents.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
CHANGED
|
@@ -10,6 +10,9 @@ import { PresenceHandle } from "./crdt/presence.js";
|
|
|
10
10
|
import { CRDTMapHandle } from "./crdt/crdtmap.js";
|
|
11
11
|
import { AwarenessHandle } from "./crdt/awareness.js";
|
|
12
12
|
import { RGAHandle } from "./crdt/rga.js";
|
|
13
|
+
import { TreeHandle } from "./crdt/tree.js";
|
|
14
|
+
import type { CrdtValidator } from "./validation/index.js";
|
|
15
|
+
import type { TreeNodeValue } from "./sync/delta.js";
|
|
13
16
|
import type { TokenClaims } from "./schema.js";
|
|
14
17
|
import type { TokenParseError, TokenExpiredError } from "./errors.js";
|
|
15
18
|
export interface GCounterSnapshotEntry {
|
|
@@ -56,7 +59,12 @@ export interface RGASnapshotEntry {
|
|
|
56
59
|
crdtId: string;
|
|
57
60
|
text: string;
|
|
58
61
|
}
|
|
59
|
-
export
|
|
62
|
+
export interface TreeSnapshotEntry {
|
|
63
|
+
type: "tree";
|
|
64
|
+
crdtId: string;
|
|
65
|
+
roots: TreeNodeValue[];
|
|
66
|
+
}
|
|
67
|
+
export type CRDTSnapshotEntry = GCounterSnapshotEntry | PNCounterSnapshotEntry | ORSetSnapshotEntry | LwwRegisterSnapshotEntry | PresenceSnapshotEntry | CRDTMapSnapshotEntry | RGASnapshotEntry | TreeSnapshotEntry;
|
|
60
68
|
export interface DeltaEvent {
|
|
61
69
|
crdtId: string;
|
|
62
70
|
type: CRDTSnapshotEntry["type"];
|
|
@@ -115,6 +123,7 @@ export declare class MeridianClient {
|
|
|
115
123
|
private readonly cmHandles;
|
|
116
124
|
private readonly awHandles;
|
|
117
125
|
private readonly rgaHandles;
|
|
126
|
+
private readonly treeHandles;
|
|
118
127
|
private readonly anyListeners;
|
|
119
128
|
private readonly deltaListeners;
|
|
120
129
|
private readonly handleUnsubs;
|
|
@@ -264,7 +273,31 @@ export declare class MeridianClient {
|
|
|
264
273
|
* doc.onChange(text => console.log(text));
|
|
265
274
|
* ```
|
|
266
275
|
*/
|
|
267
|
-
rga(crdtId: string
|
|
276
|
+
rga(crdtId: string, opts?: {
|
|
277
|
+
validator?: CrdtValidator;
|
|
278
|
+
}): RGAHandle;
|
|
279
|
+
/**
|
|
280
|
+
* Returns a handle for a TreeCRDT — a convergent hierarchical tree.
|
|
281
|
+
*
|
|
282
|
+
* Use this for outlines, document trees, mind maps, or any nested structure
|
|
283
|
+
* that needs concurrent editing. Concurrent moves use Kleppmann (2021)
|
|
284
|
+
* move semantics: cycle-creating moves are discarded, all replicas converge.
|
|
285
|
+
*
|
|
286
|
+
* Handles are cached by `crdtId`; the same handle is returned for repeated calls.
|
|
287
|
+
*
|
|
288
|
+
* @param crdtId - Logical CRDT identifier (e.g. `"tree:outline"`).
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* ```ts
|
|
292
|
+
* const tree = client.tree('doc:outline');
|
|
293
|
+
* const rootId = tree.addNode(null, 'a0', 'Introduction');
|
|
294
|
+
* const childId = tree.addNode(rootId, 'a0', 'Chapter 1');
|
|
295
|
+
* tree.onChange(t => console.log(t.roots));
|
|
296
|
+
* ```
|
|
297
|
+
*/
|
|
298
|
+
tree(crdtId: string, opts?: {
|
|
299
|
+
validator?: CrdtValidator;
|
|
300
|
+
}): TreeHandle;
|
|
268
301
|
/**
|
|
269
302
|
* Returns a handle for an ephemeral awareness channel.
|
|
270
303
|
*
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -9,7 +9,8 @@ import { PresenceHandle } from "./crdt/presence.js";
|
|
|
9
9
|
import { CRDTMapHandle } from "./crdt/crdtmap.js";
|
|
10
10
|
import { AwarenessHandle } from "./crdt/awareness.js";
|
|
11
11
|
import { RGAHandle } from "./crdt/rga.js";
|
|
12
|
-
import {
|
|
12
|
+
import { TreeHandle } from "./crdt/tree.js";
|
|
13
|
+
import { decodeGCounterDelta, decodePNCounterDelta, decodeORSetDelta, decodeLwwDelta, decodePresenceDelta, decodeCRDTMapDelta, decodeRGADelta, decodeTreeDelta, } from "./sync/delta.js";
|
|
13
14
|
import { parseAndValidateToken } from "./auth/token.js";
|
|
14
15
|
/**
|
|
15
16
|
* The main entry point for the Meridian real-time CRDT SDK.
|
|
@@ -52,6 +53,7 @@ export class MeridianClient {
|
|
|
52
53
|
cmHandles = new Map();
|
|
53
54
|
awHandles = new Map();
|
|
54
55
|
rgaHandles = new Map();
|
|
56
|
+
treeHandles = new Map();
|
|
55
57
|
anyListeners = new Set();
|
|
56
58
|
deltaListeners = new Set();
|
|
57
59
|
handleUnsubs = [];
|
|
@@ -280,16 +282,45 @@ export class MeridianClient {
|
|
|
280
282
|
* doc.onChange(text => console.log(text));
|
|
281
283
|
* ```
|
|
282
284
|
*/
|
|
283
|
-
rga(crdtId) {
|
|
285
|
+
rga(crdtId, opts) {
|
|
284
286
|
let handle = this.rgaHandles.get(crdtId);
|
|
285
287
|
if (!handle) {
|
|
286
|
-
handle = new RGAHandle({ crdtId, clientId: this.clientId, transport: this.transport });
|
|
288
|
+
handle = new RGAHandle({ crdtId, clientId: this.clientId, transport: this.transport, ...(opts?.validator !== undefined && { validator: opts.validator }) });
|
|
287
289
|
this.rgaHandles.set(crdtId, handle);
|
|
288
290
|
this.transport.subscribe(crdtId);
|
|
289
291
|
this.handleUnsubs.push(handle.onChange(() => { this.notifyAnyChange(); }));
|
|
290
292
|
}
|
|
291
293
|
return handle;
|
|
292
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* Returns a handle for a TreeCRDT — a convergent hierarchical tree.
|
|
297
|
+
*
|
|
298
|
+
* Use this for outlines, document trees, mind maps, or any nested structure
|
|
299
|
+
* that needs concurrent editing. Concurrent moves use Kleppmann (2021)
|
|
300
|
+
* move semantics: cycle-creating moves are discarded, all replicas converge.
|
|
301
|
+
*
|
|
302
|
+
* Handles are cached by `crdtId`; the same handle is returned for repeated calls.
|
|
303
|
+
*
|
|
304
|
+
* @param crdtId - Logical CRDT identifier (e.g. `"tree:outline"`).
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* ```ts
|
|
308
|
+
* const tree = client.tree('doc:outline');
|
|
309
|
+
* const rootId = tree.addNode(null, 'a0', 'Introduction');
|
|
310
|
+
* const childId = tree.addNode(rootId, 'a0', 'Chapter 1');
|
|
311
|
+
* tree.onChange(t => console.log(t.roots));
|
|
312
|
+
* ```
|
|
313
|
+
*/
|
|
314
|
+
tree(crdtId, opts) {
|
|
315
|
+
let handle = this.treeHandles.get(crdtId);
|
|
316
|
+
if (!handle) {
|
|
317
|
+
handle = new TreeHandle({ crdtId, clientId: this.clientId, transport: this.transport, ...(opts?.validator !== undefined && { validator: opts.validator }) });
|
|
318
|
+
this.treeHandles.set(crdtId, handle);
|
|
319
|
+
this.transport.subscribe(crdtId);
|
|
320
|
+
this.handleUnsubs.push(handle.onChange(() => { this.notifyAnyChange(); }));
|
|
321
|
+
}
|
|
322
|
+
return handle;
|
|
323
|
+
}
|
|
293
324
|
/**
|
|
294
325
|
* Returns a handle for an ephemeral awareness channel.
|
|
295
326
|
*
|
|
@@ -378,6 +409,8 @@ export class MeridianClient {
|
|
|
378
409
|
crdts.push({ type: "crdtmap", crdtId, value: h.value() });
|
|
379
410
|
for (const [crdtId, h] of this.rgaHandles)
|
|
380
411
|
crdts.push({ type: "rga", crdtId, text: h.value() });
|
|
412
|
+
for (const [crdtId, h] of this.treeHandles)
|
|
413
|
+
crdts.push({ type: "tree", crdtId, roots: h.value().roots });
|
|
381
414
|
return {
|
|
382
415
|
namespace: this.namespace,
|
|
383
416
|
clientId: this.clientId,
|
|
@@ -479,6 +512,15 @@ export class MeridianClient {
|
|
|
479
512
|
}
|
|
480
513
|
catch { /* stale */ }
|
|
481
514
|
this.notifyDelta(crdt_id, "rga");
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
const treeHandle = this.treeHandles.get(crdt_id);
|
|
518
|
+
if (treeHandle) {
|
|
519
|
+
try {
|
|
520
|
+
treeHandle.applyDelta(decodeTreeDelta(delta_bytes));
|
|
521
|
+
}
|
|
522
|
+
catch { /* stale */ }
|
|
523
|
+
this.notifyDelta(crdt_id, "tree");
|
|
482
524
|
}
|
|
483
525
|
}
|
|
484
526
|
notifyDelta(crdtId, type) {
|