@liveblocks/core 2.25.0-aiprivatebeta1 → 2.25.0-aiprivatebeta11
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/dist/index.cjs +378 -305
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +263 -118
- package/dist/index.d.ts +263 -118
- package/dist/index.js +294 -221
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
|
|
7
7
|
// src/version.ts
|
|
8
8
|
var PKG_NAME = "@liveblocks/core";
|
|
9
|
-
var PKG_VERSION = "2.25.0-
|
|
9
|
+
var PKG_VERSION = "2.25.0-aiprivatebeta11";
|
|
10
10
|
var PKG_FORMAT = "esm";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -188,6 +188,9 @@ var warnWithTitle = wrapWithTitle("warn");
|
|
|
188
188
|
var errorWithTitle = wrapWithTitle("error");
|
|
189
189
|
|
|
190
190
|
// src/lib/guards.ts
|
|
191
|
+
function isDefined(value) {
|
|
192
|
+
return value !== null && value !== void 0;
|
|
193
|
+
}
|
|
191
194
|
function isPlainObject(blob) {
|
|
192
195
|
return blob !== null && typeof blob === "object" && Object.prototype.toString.call(blob) === "[object Object]";
|
|
193
196
|
}
|
|
@@ -3685,11 +3688,6 @@ function parseAuthToken(rawTokenString) {
|
|
|
3685
3688
|
function appendDelta(content, delta) {
|
|
3686
3689
|
const lastPart = content[content.length - 1];
|
|
3687
3690
|
switch (delta.type) {
|
|
3688
|
-
case "reasoning":
|
|
3689
|
-
case "text":
|
|
3690
|
-
case "tool-call":
|
|
3691
|
-
content.push(delta);
|
|
3692
|
-
break;
|
|
3693
3691
|
case "text-delta":
|
|
3694
3692
|
if (lastPart?.type === "text") {
|
|
3695
3693
|
lastPart.text += delta.textDelta;
|
|
@@ -3700,15 +3698,16 @@ function appendDelta(content, delta) {
|
|
|
3700
3698
|
case "reasoning-delta":
|
|
3701
3699
|
if (lastPart?.type === "reasoning") {
|
|
3702
3700
|
lastPart.text += delta.textDelta;
|
|
3703
|
-
lastPart.signature ??= delta.signature;
|
|
3704
3701
|
} else {
|
|
3705
3702
|
content.push({
|
|
3706
3703
|
type: "reasoning",
|
|
3707
|
-
text: delta.textDelta ?? ""
|
|
3708
|
-
signature: delta.signature
|
|
3704
|
+
text: delta.textDelta ?? ""
|
|
3709
3705
|
});
|
|
3710
3706
|
}
|
|
3711
3707
|
break;
|
|
3708
|
+
case "tool-invocation":
|
|
3709
|
+
content.push(delta);
|
|
3710
|
+
break;
|
|
3712
3711
|
default:
|
|
3713
3712
|
return assertNever(delta, "Unhandled case");
|
|
3714
3713
|
}
|
|
@@ -3716,48 +3715,131 @@ function appendDelta(content, delta) {
|
|
|
3716
3715
|
|
|
3717
3716
|
// src/ai.ts
|
|
3718
3717
|
var DEFAULT_REQUEST_TIMEOUT = 4e3;
|
|
3719
|
-
|
|
3718
|
+
function defineAiTool() {
|
|
3719
|
+
return (def) => {
|
|
3720
|
+
return def;
|
|
3721
|
+
};
|
|
3722
|
+
}
|
|
3723
|
+
var KnowledgeStack = class {
|
|
3724
|
+
#_layers;
|
|
3725
|
+
#stack;
|
|
3726
|
+
// / \
|
|
3727
|
+
// knowledge key "layer" key
|
|
3728
|
+
// (random, or optionally (one entry per mounted component)
|
|
3729
|
+
// set by user)
|
|
3730
|
+
#_cache;
|
|
3731
|
+
constructor() {
|
|
3732
|
+
this.#_layers = /* @__PURE__ */ new Set();
|
|
3733
|
+
this.#stack = new DefaultMap(
|
|
3734
|
+
() => /* @__PURE__ */ new Map()
|
|
3735
|
+
);
|
|
3736
|
+
this.#_cache = void 0;
|
|
3737
|
+
}
|
|
3738
|
+
// Typically a useId()
|
|
3739
|
+
registerLayer(uniqueLayerId) {
|
|
3740
|
+
const layerKey = uniqueLayerId;
|
|
3741
|
+
if (this.#_layers.has(layerKey))
|
|
3742
|
+
raise(`Layer '${layerKey}' already exists, provide a unique layer id`);
|
|
3743
|
+
this.#_layers.add(layerKey);
|
|
3744
|
+
return layerKey;
|
|
3745
|
+
}
|
|
3746
|
+
deregisterLayer(layerKey) {
|
|
3747
|
+
this.#_layers.delete(layerKey);
|
|
3748
|
+
let deleted = false;
|
|
3749
|
+
for (const [key, knowledge] of this.#stack) {
|
|
3750
|
+
if (knowledge.delete(layerKey)) {
|
|
3751
|
+
deleted = true;
|
|
3752
|
+
}
|
|
3753
|
+
if (knowledge.size === 0)
|
|
3754
|
+
this.#stack.delete(key);
|
|
3755
|
+
}
|
|
3756
|
+
if (deleted) {
|
|
3757
|
+
this.invalidate();
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3760
|
+
get() {
|
|
3761
|
+
return this.#_cache ??= this.#recompute();
|
|
3762
|
+
}
|
|
3763
|
+
invalidate() {
|
|
3764
|
+
this.#_cache = void 0;
|
|
3765
|
+
}
|
|
3766
|
+
#recompute() {
|
|
3767
|
+
return Array.from(this.#stack.values()).flatMap(
|
|
3768
|
+
(layer) => (
|
|
3769
|
+
// Return only the last item (returns [] when empty)
|
|
3770
|
+
Array.from(layer.values()).slice(-1).filter(isDefined)
|
|
3771
|
+
)
|
|
3772
|
+
);
|
|
3773
|
+
}
|
|
3774
|
+
updateKnowledge(layerKey, key, data) {
|
|
3775
|
+
if (!this.#_layers.has(layerKey)) raise(`Unknown layer key: ${layerKey}`);
|
|
3776
|
+
this.#stack.getOrCreate(key).set(layerKey, data);
|
|
3777
|
+
this.invalidate();
|
|
3778
|
+
}
|
|
3779
|
+
};
|
|
3720
3780
|
function now() {
|
|
3721
3781
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
3722
3782
|
}
|
|
3783
|
+
var kWILDCARD = Symbol("*");
|
|
3723
3784
|
function createStore_forTools() {
|
|
3724
|
-
const toolsByChatId\u03A3 = new DefaultMap(
|
|
3725
|
-
|
|
3726
|
-
return new
|
|
3785
|
+
const toolsByChatId\u03A3 = new DefaultMap(
|
|
3786
|
+
(_chatId) => {
|
|
3787
|
+
return new DefaultMap((_name) => {
|
|
3788
|
+
return new Signal(void 0);
|
|
3789
|
+
});
|
|
3790
|
+
}
|
|
3791
|
+
);
|
|
3792
|
+
const globalOrScopedTool\u03A3 = new DefaultMap((nameAndChat) => {
|
|
3793
|
+
const [name, chatId] = tryParseJson(nameAndChat);
|
|
3794
|
+
return DerivedSignal.from(() => {
|
|
3795
|
+
return (
|
|
3796
|
+
// A tool that's registered and scoped to a specific chat ID...
|
|
3797
|
+
(chatId !== void 0 ? toolsByChatId\u03A3.get(chatId)?.get(name) : void 0)?.get() ?? // ...or a globally registered tool
|
|
3798
|
+
toolsByChatId\u03A3.getOrCreate(kWILDCARD).get(name)?.get()
|
|
3799
|
+
);
|
|
3727
3800
|
});
|
|
3728
3801
|
});
|
|
3729
|
-
function
|
|
3730
|
-
|
|
3802
|
+
function getTool\u03A3(name, chatId) {
|
|
3803
|
+
const key = JSON.stringify(chatId !== void 0 ? [name, chatId] : [name]);
|
|
3804
|
+
return globalOrScopedTool\u03A3.getOrCreate(key);
|
|
3731
3805
|
}
|
|
3732
|
-
function
|
|
3733
|
-
|
|
3806
|
+
function registerTool(name, tool, chatId) {
|
|
3807
|
+
if (!tool.execute && !tool.render) {
|
|
3808
|
+
throw new Error(
|
|
3809
|
+
"A tool definition must have an execute() function, a render() function, or both."
|
|
3810
|
+
);
|
|
3811
|
+
}
|
|
3812
|
+
const key = chatId ?? kWILDCARD;
|
|
3813
|
+
toolsByChatId\u03A3.getOrCreate(key).getOrCreate(name).set(tool);
|
|
3814
|
+
return () => unregisterTool(key, name);
|
|
3734
3815
|
}
|
|
3735
|
-
function
|
|
3816
|
+
function unregisterTool(chatId, name) {
|
|
3736
3817
|
const tools = toolsByChatId\u03A3.get(chatId);
|
|
3737
3818
|
if (tools === void 0) return;
|
|
3738
|
-
const tool = tools.get(
|
|
3819
|
+
const tool = tools.get(name);
|
|
3739
3820
|
if (tool === void 0) return;
|
|
3740
3821
|
tool.set(void 0);
|
|
3741
3822
|
}
|
|
3742
|
-
function
|
|
3743
|
-
const
|
|
3744
|
-
|
|
3745
|
-
return Array.from(
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
};
|
|
3751
|
-
})
|
|
3823
|
+
function getToolDescriptions(chatId) {
|
|
3824
|
+
const globalTools\u03A3 = toolsByChatId\u03A3.get(kWILDCARD);
|
|
3825
|
+
const scopedTools\u03A3 = toolsByChatId\u03A3.get(chatId);
|
|
3826
|
+
return Array.from([
|
|
3827
|
+
...globalTools\u03A3?.entries() ?? [],
|
|
3828
|
+
...scopedTools\u03A3?.entries() ?? []
|
|
3829
|
+
]).flatMap(([name, tool\u03A3]) => {
|
|
3830
|
+
const tool = tool\u03A3.get();
|
|
3831
|
+
return tool ? [{ name, description: tool.description, parameters: tool.parameters }] : [];
|
|
3832
|
+
});
|
|
3752
3833
|
}
|
|
3753
3834
|
return {
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
removeToolDefinition
|
|
3835
|
+
getToolDescriptions,
|
|
3836
|
+
getTool\u03A3,
|
|
3837
|
+
registerTool
|
|
3758
3838
|
};
|
|
3759
3839
|
}
|
|
3760
|
-
function createStore_forChatMessages() {
|
|
3840
|
+
function createStore_forChatMessages(toolsStore, setToolResult) {
|
|
3841
|
+
const autoExecutableMessages = /* @__PURE__ */ new Set();
|
|
3842
|
+
const seenToolCallIds = /* @__PURE__ */ new Set();
|
|
3761
3843
|
const messagePoolByChatId\u03A3 = new DefaultMap(
|
|
3762
3844
|
(_chatId) => new MutableSignal(
|
|
3763
3845
|
new TreePool(
|
|
@@ -3767,7 +3849,7 @@ function createStore_forChatMessages() {
|
|
|
3767
3849
|
)
|
|
3768
3850
|
)
|
|
3769
3851
|
);
|
|
3770
|
-
const
|
|
3852
|
+
const generatingMessages\u03A3 = new MutableSignal(
|
|
3771
3853
|
/* @__PURE__ */ new Map()
|
|
3772
3854
|
);
|
|
3773
3855
|
function createOptimistically(chatId, role, parentId, third) {
|
|
@@ -3781,7 +3863,8 @@ function createStore_forChatMessages() {
|
|
|
3781
3863
|
role,
|
|
3782
3864
|
parentId,
|
|
3783
3865
|
createdAt,
|
|
3784
|
-
content
|
|
3866
|
+
content,
|
|
3867
|
+
_optimistic: true
|
|
3785
3868
|
});
|
|
3786
3869
|
} else {
|
|
3787
3870
|
upsert({
|
|
@@ -3790,8 +3873,9 @@ function createStore_forChatMessages() {
|
|
|
3790
3873
|
role,
|
|
3791
3874
|
parentId,
|
|
3792
3875
|
createdAt,
|
|
3793
|
-
status: "
|
|
3794
|
-
contentSoFar: []
|
|
3876
|
+
status: "generating",
|
|
3877
|
+
contentSoFar: [],
|
|
3878
|
+
_optimistic: true
|
|
3795
3879
|
});
|
|
3796
3880
|
}
|
|
3797
3881
|
return id;
|
|
@@ -3808,7 +3892,7 @@ function createStore_forChatMessages() {
|
|
|
3808
3892
|
if (!chatMsgs\u03A3) return;
|
|
3809
3893
|
const existing = chatMsgs\u03A3.get().get(messageId);
|
|
3810
3894
|
if (!existing || existing.deletedAt) return;
|
|
3811
|
-
if (existing.role === "assistant" &&
|
|
3895
|
+
if (existing.role === "assistant" && existing.status !== "completed") {
|
|
3812
3896
|
upsert({ ...existing, deletedAt: now(), contentSoFar: [] });
|
|
3813
3897
|
} else {
|
|
3814
3898
|
upsert({ ...existing, deletedAt: now(), content: [] });
|
|
@@ -3823,19 +3907,59 @@ function createStore_forChatMessages() {
|
|
|
3823
3907
|
batch(() => {
|
|
3824
3908
|
const chatMsgs\u03A3 = messagePoolByChatId\u03A3.getOrCreate(message.chatId);
|
|
3825
3909
|
chatMsgs\u03A3.mutate((pool) => pool.upsert(message));
|
|
3826
|
-
if (message.role === "assistant" && message.status === "
|
|
3827
|
-
|
|
3910
|
+
if (message.role === "assistant" && message.status === "generating") {
|
|
3911
|
+
generatingMessages\u03A3.mutate((lut) => {
|
|
3828
3912
|
lut.set(message.id, structuredClone(message));
|
|
3829
3913
|
});
|
|
3830
3914
|
} else {
|
|
3831
|
-
|
|
3915
|
+
generatingMessages\u03A3.mutate((lut) => {
|
|
3832
3916
|
lut.delete(message.id);
|
|
3833
3917
|
});
|
|
3834
3918
|
}
|
|
3919
|
+
if (message.role === "assistant" && message.status === "awaiting-tool") {
|
|
3920
|
+
for (const toolCall of message.contentSoFar.filter(
|
|
3921
|
+
(part) => part.type === "tool-invocation" && part.status === "executing"
|
|
3922
|
+
)) {
|
|
3923
|
+
if (seenToolCallIds.has(toolCall.toolCallId)) {
|
|
3924
|
+
continue;
|
|
3925
|
+
}
|
|
3926
|
+
seenToolCallIds.add(toolCall.toolCallId);
|
|
3927
|
+
const toolDef = toolsStore.getTool\u03A3(toolCall.toolName, message.chatId).get();
|
|
3928
|
+
const respondSync = (result) => {
|
|
3929
|
+
setToolResult(
|
|
3930
|
+
message.chatId,
|
|
3931
|
+
message.id,
|
|
3932
|
+
toolCall.toolCallId,
|
|
3933
|
+
result
|
|
3934
|
+
// TODO Pass in AiGenerationOptions here, or make the backend use the same options
|
|
3935
|
+
).catch((err) => {
|
|
3936
|
+
error2(
|
|
3937
|
+
`Error trying to respond to tool-call: ${String(err)} (in respond())`
|
|
3938
|
+
);
|
|
3939
|
+
});
|
|
3940
|
+
};
|
|
3941
|
+
const executeFn = toolDef?.execute;
|
|
3942
|
+
if (executeFn && autoExecutableMessages.has(message.id)) {
|
|
3943
|
+
(async () => {
|
|
3944
|
+
const result = await executeFn(toolCall.args, {
|
|
3945
|
+
toolName: toolCall.toolName,
|
|
3946
|
+
toolCallId: toolCall.toolCallId
|
|
3947
|
+
});
|
|
3948
|
+
respondSync(result);
|
|
3949
|
+
})().catch((err) => {
|
|
3950
|
+
error2(
|
|
3951
|
+
`Error trying to respond to tool-call: ${String(err)} (in execute())`
|
|
3952
|
+
);
|
|
3953
|
+
});
|
|
3954
|
+
}
|
|
3955
|
+
}
|
|
3956
|
+
} else {
|
|
3957
|
+
autoExecutableMessages.delete(message.id);
|
|
3958
|
+
}
|
|
3835
3959
|
});
|
|
3836
3960
|
}
|
|
3837
3961
|
function addDelta(messageId, delta) {
|
|
3838
|
-
|
|
3962
|
+
generatingMessages\u03A3.mutate((lut) => {
|
|
3839
3963
|
const message = lut.get(messageId);
|
|
3840
3964
|
if (message === void 0) return false;
|
|
3841
3965
|
appendDelta(message.contentSoFar, delta);
|
|
@@ -3843,10 +3967,10 @@ function createStore_forChatMessages() {
|
|
|
3843
3967
|
return true;
|
|
3844
3968
|
});
|
|
3845
3969
|
}
|
|
3846
|
-
function*
|
|
3970
|
+
function* iterGeneratingMessages() {
|
|
3847
3971
|
for (const chatMsgs\u03A3 of messagePoolByChatId\u03A3.values()) {
|
|
3848
3972
|
for (const m of chatMsgs\u03A3.get()) {
|
|
3849
|
-
if (m.role === "assistant" && m.status === "
|
|
3973
|
+
if (m.role === "assistant" && m.status === "generating" && !m._optimistic) {
|
|
3850
3974
|
yield m;
|
|
3851
3975
|
}
|
|
3852
3976
|
}
|
|
@@ -3854,9 +3978,18 @@ function createStore_forChatMessages() {
|
|
|
3854
3978
|
}
|
|
3855
3979
|
function failAllPending() {
|
|
3856
3980
|
batch(() => {
|
|
3857
|
-
|
|
3981
|
+
generatingMessages\u03A3.mutate((lut) => {
|
|
3982
|
+
let deleted = false;
|
|
3983
|
+
for (const [k, v] of lut) {
|
|
3984
|
+
if (!v._optimistic) {
|
|
3985
|
+
lut.delete(k);
|
|
3986
|
+
deleted = true;
|
|
3987
|
+
}
|
|
3988
|
+
}
|
|
3989
|
+
return deleted;
|
|
3990
|
+
});
|
|
3858
3991
|
upsertMany(
|
|
3859
|
-
Array.from(
|
|
3992
|
+
Array.from(iterGeneratingMessages()).map(
|
|
3860
3993
|
(message) => ({
|
|
3861
3994
|
...message,
|
|
3862
3995
|
status: "failed",
|
|
@@ -3891,11 +4024,20 @@ function createStore_forChatMessages() {
|
|
|
3891
4024
|
}
|
|
3892
4025
|
function selectSpine(leaf) {
|
|
3893
4026
|
const spine = [];
|
|
4027
|
+
let lastVisitedMessage = null;
|
|
3894
4028
|
for (const message2 of pool.walkUp(leaf.id)) {
|
|
3895
4029
|
const prev = first(pool.walkLeft(message2.id, isAlive))?.id ?? null;
|
|
3896
4030
|
const next = first(pool.walkRight(message2.id, isAlive))?.id ?? null;
|
|
3897
4031
|
if (!message2.deletedAt || prev || next) {
|
|
3898
|
-
|
|
4032
|
+
const node = {
|
|
4033
|
+
...message2,
|
|
4034
|
+
navigation: { parent: null, prev, next }
|
|
4035
|
+
};
|
|
4036
|
+
if (lastVisitedMessage !== null) {
|
|
4037
|
+
lastVisitedMessage.navigation.parent = node.id;
|
|
4038
|
+
}
|
|
4039
|
+
lastVisitedMessage = node;
|
|
4040
|
+
spine.push(node);
|
|
3899
4041
|
}
|
|
3900
4042
|
}
|
|
3901
4043
|
return spine.reverse();
|
|
@@ -3921,18 +4063,6 @@ function createStore_forChatMessages() {
|
|
|
3921
4063
|
}
|
|
3922
4064
|
return fallback();
|
|
3923
4065
|
}
|
|
3924
|
-
function getLatestUserMessageAncestor(chatId, messageId) {
|
|
3925
|
-
const pool = messagePoolByChatId\u03A3.getOrCreate(chatId).get();
|
|
3926
|
-
const message = pool.get(messageId);
|
|
3927
|
-
if (!message) return null;
|
|
3928
|
-
if (message.role === "user") return message.id;
|
|
3929
|
-
for (const m of pool.walkUp(message.id)) {
|
|
3930
|
-
if (m.role === "user" && !m.deletedAt) {
|
|
3931
|
-
return m.id;
|
|
3932
|
-
}
|
|
3933
|
-
}
|
|
3934
|
-
return null;
|
|
3935
|
-
}
|
|
3936
4066
|
const immutableMessagesByBranch = new DefaultMap((chatId) => {
|
|
3937
4067
|
return new DefaultMap((branchId) => {
|
|
3938
4068
|
const messages\u03A3 = DerivedSignal.from(() => {
|
|
@@ -3940,16 +4070,16 @@ function createStore_forChatMessages() {
|
|
|
3940
4070
|
return selectBranch(pool, branchId);
|
|
3941
4071
|
}, shallow2);
|
|
3942
4072
|
return DerivedSignal.from(() => {
|
|
3943
|
-
const
|
|
4073
|
+
const generatingMessages = generatingMessages\u03A3.get();
|
|
3944
4074
|
return messages\u03A3.get().map((message) => {
|
|
3945
|
-
if (message.role !== "assistant" || message.status !== "
|
|
4075
|
+
if (message.role !== "assistant" || message.status !== "generating") {
|
|
3946
4076
|
return message;
|
|
3947
4077
|
}
|
|
3948
|
-
const
|
|
3949
|
-
if (
|
|
4078
|
+
const generatingMessage = generatingMessages.get(message.id);
|
|
4079
|
+
if (generatingMessage === void 0) return message;
|
|
3950
4080
|
return {
|
|
3951
4081
|
...message,
|
|
3952
|
-
contentSoFar:
|
|
4082
|
+
contentSoFar: generatingMessage.contentSoFar
|
|
3953
4083
|
};
|
|
3954
4084
|
});
|
|
3955
4085
|
}, shallow);
|
|
@@ -3958,21 +4088,10 @@ function createStore_forChatMessages() {
|
|
|
3958
4088
|
function getChatMessagesForBranch\u03A3(chatId, branch) {
|
|
3959
4089
|
return immutableMessagesByBranch.getOrCreate(chatId).getOrCreate(branch || null);
|
|
3960
4090
|
}
|
|
3961
|
-
const messagesByChatId\u03A3 = new DefaultMap((chatId) => {
|
|
3962
|
-
return DerivedSignal.from(() => {
|
|
3963
|
-
const pool = messagePoolByChatId\u03A3.getOrCreate(chatId).get();
|
|
3964
|
-
return Array.from(pool.sorted);
|
|
3965
|
-
});
|
|
3966
|
-
});
|
|
3967
|
-
function getMessagesForChat\u03A3(chatId) {
|
|
3968
|
-
return messagesByChatId\u03A3.getOrCreate(chatId);
|
|
3969
|
-
}
|
|
3970
4091
|
return {
|
|
3971
4092
|
// Readers
|
|
3972
4093
|
getMessageById,
|
|
3973
4094
|
getChatMessagesForBranch\u03A3,
|
|
3974
|
-
getMessagesForChat\u03A3,
|
|
3975
|
-
getLatestUserMessageAncestor,
|
|
3976
4095
|
// Mutations
|
|
3977
4096
|
createOptimistically,
|
|
3978
4097
|
upsert,
|
|
@@ -3980,20 +4099,23 @@ function createStore_forChatMessages() {
|
|
|
3980
4099
|
remove,
|
|
3981
4100
|
removeByChatId,
|
|
3982
4101
|
addDelta,
|
|
3983
|
-
failAllPending
|
|
4102
|
+
failAllPending,
|
|
4103
|
+
allowAutoExecuteToolCall(messageId) {
|
|
4104
|
+
autoExecutableMessages.add(messageId);
|
|
4105
|
+
}
|
|
3984
4106
|
};
|
|
3985
4107
|
}
|
|
3986
4108
|
function createStore_forUserAiChats() {
|
|
3987
|
-
const
|
|
4109
|
+
const allChatsInclDeleted\u03A3 = new MutableSignal(
|
|
3988
4110
|
SortedList.with((x, y) => y.createdAt < x.createdAt)
|
|
3989
4111
|
);
|
|
3990
|
-
const
|
|
3991
|
-
() => Array.from(
|
|
4112
|
+
const nonDeletedChats\u03A3 = DerivedSignal.from(
|
|
4113
|
+
() => Array.from(allChatsInclDeleted\u03A3.get()).filter((c) => !c.deletedAt)
|
|
3992
4114
|
);
|
|
3993
4115
|
function upsertMany(chats) {
|
|
3994
|
-
|
|
4116
|
+
allChatsInclDeleted\u03A3.mutate((list) => {
|
|
3995
4117
|
for (const chat of chats) {
|
|
3996
|
-
|
|
4118
|
+
list.removeBy((c) => c.id === chat.id, 1);
|
|
3997
4119
|
list.add(chat);
|
|
3998
4120
|
}
|
|
3999
4121
|
});
|
|
@@ -4001,15 +4123,26 @@ function createStore_forUserAiChats() {
|
|
|
4001
4123
|
function upsert(chat) {
|
|
4002
4124
|
upsertMany([chat]);
|
|
4003
4125
|
}
|
|
4004
|
-
function
|
|
4005
|
-
|
|
4126
|
+
function markDeleted(chatId) {
|
|
4127
|
+
allChatsInclDeleted\u03A3.mutate((list) => {
|
|
4128
|
+
const chat = list.find((c) => c.id === chatId);
|
|
4129
|
+
if (!chat) return false;
|
|
4130
|
+
upsert({ ...chat, deletedAt: now() });
|
|
4131
|
+
return void 0;
|
|
4132
|
+
});
|
|
4133
|
+
}
|
|
4134
|
+
function getChatById(chatId) {
|
|
4135
|
+
return Array.from(allChatsInclDeleted\u03A3.get()).find(
|
|
4136
|
+
(chat) => chat.id === chatId
|
|
4137
|
+
);
|
|
4006
4138
|
}
|
|
4007
4139
|
return {
|
|
4008
|
-
chats\u03A3,
|
|
4140
|
+
chats\u03A3: nonDeletedChats\u03A3,
|
|
4141
|
+
getChatById,
|
|
4009
4142
|
// Mutations
|
|
4010
4143
|
upsert,
|
|
4011
4144
|
upsertMany,
|
|
4012
|
-
|
|
4145
|
+
markDeleted
|
|
4013
4146
|
};
|
|
4014
4147
|
}
|
|
4015
4148
|
function createAi(config) {
|
|
@@ -4019,10 +4152,9 @@ function createAi(config) {
|
|
|
4019
4152
|
false
|
|
4020
4153
|
// AI doesn't have actors (yet, but it will)
|
|
4021
4154
|
);
|
|
4022
|
-
const clientId = nanoid(7);
|
|
4023
4155
|
const chatsStore = createStore_forUserAiChats();
|
|
4024
|
-
const messagesStore = createStore_forChatMessages();
|
|
4025
4156
|
const toolsStore = createStore_forTools();
|
|
4157
|
+
const messagesStore = createStore_forChatMessages(toolsStore, setToolResult);
|
|
4026
4158
|
const context = {
|
|
4027
4159
|
staticSessionInfoSig: new Signal(null),
|
|
4028
4160
|
dynamicSessionInfoSig: new Signal(null),
|
|
@@ -4030,11 +4162,10 @@ function createAi(config) {
|
|
|
4030
4162
|
chatsStore,
|
|
4031
4163
|
messagesStore,
|
|
4032
4164
|
toolsStore,
|
|
4033
|
-
|
|
4165
|
+
knowledge: new KnowledgeStack()
|
|
4034
4166
|
};
|
|
4035
4167
|
let lastTokenKey;
|
|
4036
|
-
function onStatusDidChange(
|
|
4037
|
-
warn("onStatusDidChange", newStatus);
|
|
4168
|
+
function onStatusDidChange(_newStatus) {
|
|
4038
4169
|
const authValue = managedSocket.authValue;
|
|
4039
4170
|
if (authValue !== null) {
|
|
4040
4171
|
const tokenKey = getBearerTokenFromAuthValue(authValue);
|
|
@@ -4070,7 +4201,6 @@ function createAi(config) {
|
|
|
4070
4201
|
}
|
|
4071
4202
|
}
|
|
4072
4203
|
function onDidConnect() {
|
|
4073
|
-
warn("onDidConnect");
|
|
4074
4204
|
}
|
|
4075
4205
|
function onDidDisconnect() {
|
|
4076
4206
|
warn("onDidDisconnect");
|
|
@@ -4112,7 +4242,7 @@ function createAi(config) {
|
|
|
4112
4242
|
context.messagesStore.remove(m.chatId, m.id);
|
|
4113
4243
|
}
|
|
4114
4244
|
for (const chatId of msg["-chats"] ?? []) {
|
|
4115
|
-
context.chatsStore.
|
|
4245
|
+
context.chatsStore.markDeleted(chatId);
|
|
4116
4246
|
context.messagesStore.removeByChatId(chatId);
|
|
4117
4247
|
}
|
|
4118
4248
|
for (const chatId of msg.clear ?? []) {
|
|
@@ -4134,34 +4264,36 @@ function createAi(config) {
|
|
|
4134
4264
|
case "get-chats":
|
|
4135
4265
|
context.chatsStore.upsertMany(msg.chats);
|
|
4136
4266
|
break;
|
|
4137
|
-
case "create-chat":
|
|
4267
|
+
case "get-or-create-chat":
|
|
4138
4268
|
context.chatsStore.upsert(msg.chat);
|
|
4139
4269
|
break;
|
|
4140
4270
|
case "delete-chat":
|
|
4141
|
-
context.chatsStore.
|
|
4271
|
+
context.chatsStore.markDeleted(msg.chatId);
|
|
4142
4272
|
context.messagesStore.removeByChatId(msg.chatId);
|
|
4143
4273
|
break;
|
|
4144
4274
|
case "get-message-tree":
|
|
4145
4275
|
context.chatsStore.upsert(msg.chat);
|
|
4146
4276
|
context.messagesStore.upsertMany(msg.messages);
|
|
4147
4277
|
break;
|
|
4148
|
-
case "add-user-message":
|
|
4149
|
-
context.messagesStore.upsert(msg.message);
|
|
4150
|
-
break;
|
|
4151
4278
|
case "delete-message":
|
|
4152
4279
|
context.messagesStore.remove(msg.chatId, msg.messageId);
|
|
4153
4280
|
break;
|
|
4154
4281
|
case "clear-chat":
|
|
4155
4282
|
context.messagesStore.removeByChatId(msg.chatId);
|
|
4156
4283
|
break;
|
|
4157
|
-
case "ask-
|
|
4158
|
-
if (msg.
|
|
4159
|
-
context.messagesStore.upsert(msg.
|
|
4160
|
-
} else {
|
|
4284
|
+
case "ask-in-chat":
|
|
4285
|
+
if (msg.sourceMessage) {
|
|
4286
|
+
context.messagesStore.upsert(msg.sourceMessage);
|
|
4161
4287
|
}
|
|
4288
|
+
context.messagesStore.upsert(msg.targetMessage);
|
|
4162
4289
|
break;
|
|
4163
4290
|
case "abort-ai":
|
|
4164
4291
|
break;
|
|
4292
|
+
case "set-tool-result":
|
|
4293
|
+
if (msg.ok) {
|
|
4294
|
+
context.messagesStore.upsert(msg.message);
|
|
4295
|
+
}
|
|
4296
|
+
break;
|
|
4165
4297
|
default:
|
|
4166
4298
|
return assertNever(msg, "Unhandled case");
|
|
4167
4299
|
}
|
|
@@ -4212,13 +4344,11 @@ function createAi(config) {
|
|
|
4212
4344
|
cursor: options.cursor
|
|
4213
4345
|
});
|
|
4214
4346
|
}
|
|
4215
|
-
function
|
|
4347
|
+
function getOrCreateChat(id, options) {
|
|
4216
4348
|
return sendClientMsgWithResponse({
|
|
4217
|
-
cmd: "create-chat",
|
|
4349
|
+
cmd: "get-or-create-chat",
|
|
4218
4350
|
id,
|
|
4219
|
-
|
|
4220
|
-
ephemeral: options?.ephemeral ?? false,
|
|
4221
|
-
metadata: options?.metadata ?? {}
|
|
4351
|
+
options
|
|
4222
4352
|
});
|
|
4223
4353
|
}
|
|
4224
4354
|
function getMessageTree(chatId) {
|
|
@@ -4227,147 +4357,89 @@ function createAi(config) {
|
|
|
4227
4357
|
chatId
|
|
4228
4358
|
});
|
|
4229
4359
|
}
|
|
4230
|
-
function
|
|
4231
|
-
|
|
4232
|
-
if (chatContext === void 0) {
|
|
4233
|
-
context.contextByChatId.set(chatId, /* @__PURE__ */ new Set([data]));
|
|
4234
|
-
} else {
|
|
4235
|
-
chatContext.add(data);
|
|
4236
|
-
}
|
|
4237
|
-
return () => {
|
|
4238
|
-
const chatContext2 = context.contextByChatId.get(chatId);
|
|
4239
|
-
if (chatContext2 !== void 0) {
|
|
4240
|
-
chatContext2.delete(data);
|
|
4241
|
-
if (chatContext2.size === 0) {
|
|
4242
|
-
context.contextByChatId.delete(chatId);
|
|
4243
|
-
}
|
|
4244
|
-
}
|
|
4245
|
-
};
|
|
4360
|
+
function registerKnowledgeLayer(uniqueLayerId) {
|
|
4361
|
+
return context.knowledge.registerLayer(uniqueLayerId);
|
|
4246
4362
|
}
|
|
4247
|
-
function
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
const
|
|
4255
|
-
const
|
|
4256
|
-
const
|
|
4257
|
-
|
|
4258
|
-
cmd: "ask-ai",
|
|
4363
|
+
function deregisterKnowledgeLayer(layerKey) {
|
|
4364
|
+
context.knowledge.deregisterLayer(layerKey);
|
|
4365
|
+
}
|
|
4366
|
+
function updateKnowledge(layerKey, data, key = nanoid()) {
|
|
4367
|
+
context.knowledge.updateKnowledge(layerKey, key, data);
|
|
4368
|
+
}
|
|
4369
|
+
async function setToolResult(chatId, messageId, toolCallId, result, options) {
|
|
4370
|
+
const knowledge = context.knowledge.get();
|
|
4371
|
+
const tools = context.toolsStore.getToolDescriptions(chatId);
|
|
4372
|
+
const resp = await sendClientMsgWithResponse({
|
|
4373
|
+
cmd: "set-tool-result",
|
|
4259
4374
|
chatId,
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4375
|
+
messageId,
|
|
4376
|
+
toolCallId,
|
|
4377
|
+
result,
|
|
4378
|
+
generationOptions: {
|
|
4379
|
+
copilotId: options?.copilotId,
|
|
4380
|
+
stream: options?.stream,
|
|
4381
|
+
timeout: options?.timeout,
|
|
4382
|
+
// Knowledge and tools aren't coming from the options, but retrieved
|
|
4383
|
+
// from the global context
|
|
4384
|
+
knowledge: knowledge.length > 0 ? knowledge : void 0,
|
|
4385
|
+
tools: tools.length > 0 ? tools : void 0
|
|
4386
|
+
}
|
|
4272
4387
|
});
|
|
4388
|
+
if (resp.ok) {
|
|
4389
|
+
messagesStore.allowAutoExecuteToolCall(resp.message.id);
|
|
4390
|
+
}
|
|
4391
|
+
return resp;
|
|
4273
4392
|
}
|
|
4274
4393
|
return Object.defineProperty(
|
|
4275
4394
|
{
|
|
4276
4395
|
[kInternal]: {
|
|
4277
|
-
|
|
4396
|
+
context
|
|
4278
4397
|
},
|
|
4279
4398
|
connect: () => managedSocket.connect(),
|
|
4280
4399
|
reconnect: () => managedSocket.reconnect(),
|
|
4281
4400
|
disconnect: () => managedSocket.disconnect(),
|
|
4282
4401
|
getChats,
|
|
4283
|
-
|
|
4402
|
+
getOrCreateChat,
|
|
4284
4403
|
deleteChat: (chatId) => {
|
|
4285
|
-
return sendClientMsgWithResponse({
|
|
4286
|
-
cmd: "delete-chat",
|
|
4287
|
-
chatId
|
|
4288
|
-
});
|
|
4404
|
+
return sendClientMsgWithResponse({ cmd: "delete-chat", chatId });
|
|
4289
4405
|
},
|
|
4290
4406
|
getMessageTree,
|
|
4291
4407
|
deleteMessage: (chatId, messageId) => sendClientMsgWithResponse({ cmd: "delete-message", chatId, messageId }),
|
|
4292
4408
|
clearChat: (chatId) => sendClientMsgWithResponse({ cmd: "clear-chat", chatId }),
|
|
4293
|
-
|
|
4294
|
-
const
|
|
4295
|
-
const
|
|
4296
|
-
|
|
4297
|
-
"
|
|
4298
|
-
parentMessageId,
|
|
4299
|
-
content
|
|
4300
|
-
);
|
|
4301
|
-
return sendClientMsgWithResponse({
|
|
4302
|
-
cmd: "add-user-message",
|
|
4303
|
-
id: newMessageId,
|
|
4409
|
+
askUserMessageInChat: async (chatId, userMessage, targetMessageId, options) => {
|
|
4410
|
+
const knowledge = context.knowledge.get();
|
|
4411
|
+
const tools = context.toolsStore.getToolDescriptions(chatId);
|
|
4412
|
+
const resp = await sendClientMsgWithResponse({
|
|
4413
|
+
cmd: "ask-in-chat",
|
|
4304
4414
|
chatId,
|
|
4305
|
-
|
|
4306
|
-
content
|
|
4307
|
-
});
|
|
4308
|
-
},
|
|
4309
|
-
ask,
|
|
4310
|
-
regenerateMessage: (chatId, messageId, options) => {
|
|
4311
|
-
const parentUserMessageId = context.messagesStore.getLatestUserMessageAncestor(chatId, messageId);
|
|
4312
|
-
if (parentUserMessageId === null) {
|
|
4313
|
-
throw new Error(
|
|
4314
|
-
`Unable to find user message ancestor for messageId: ${messageId}`
|
|
4315
|
-
);
|
|
4316
|
-
}
|
|
4317
|
-
return ask(chatId, parentUserMessageId, options);
|
|
4318
|
-
},
|
|
4319
|
-
addUserMessageAndAsk: async (chatId, parentMessageId, message, options) => {
|
|
4320
|
-
const content = [{ type: "text", text: message }];
|
|
4321
|
-
const newMessageId = context.messagesStore.createOptimistically(
|
|
4322
|
-
chatId,
|
|
4323
|
-
"user",
|
|
4324
|
-
parentMessageId,
|
|
4325
|
-
content
|
|
4326
|
-
);
|
|
4327
|
-
const targetMessageId = context.messagesStore.createOptimistically(
|
|
4328
|
-
chatId,
|
|
4329
|
-
"assistant",
|
|
4330
|
-
newMessageId
|
|
4331
|
-
);
|
|
4332
|
-
await sendClientMsgWithResponse({
|
|
4333
|
-
cmd: "add-user-message",
|
|
4334
|
-
id: newMessageId,
|
|
4335
|
-
chatId,
|
|
4336
|
-
parentMessageId,
|
|
4337
|
-
content
|
|
4338
|
-
});
|
|
4339
|
-
const copilotId = options?.copilotId;
|
|
4340
|
-
const stream = options?.stream ?? false;
|
|
4341
|
-
const timeout = options?.timeout ?? DEFAULT_AI_TIMEOUT;
|
|
4342
|
-
const chatContext = context.contextByChatId.get(chatId);
|
|
4343
|
-
return sendClientMsgWithResponse({
|
|
4344
|
-
cmd: "ask-ai",
|
|
4345
|
-
chatId,
|
|
4346
|
-
sourceMessageId: newMessageId,
|
|
4415
|
+
sourceMessage: userMessage,
|
|
4347
4416
|
targetMessageId,
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
context: chatContext ? Array.from(chatContext.values()) : void 0
|
|
4417
|
+
generationOptions: {
|
|
4418
|
+
copilotId: options?.copilotId,
|
|
4419
|
+
stream: options?.stream,
|
|
4420
|
+
timeout: options?.timeout,
|
|
4421
|
+
// Knowledge and tools aren't coming from the options, but retrieved
|
|
4422
|
+
// from the global context
|
|
4423
|
+
knowledge: knowledge.length > 0 ? knowledge : void 0,
|
|
4424
|
+
tools: tools.length > 0 ? tools : void 0
|
|
4425
|
+
}
|
|
4358
4426
|
});
|
|
4427
|
+
messagesStore.allowAutoExecuteToolCall(resp.targetMessage.id);
|
|
4428
|
+
return resp;
|
|
4359
4429
|
},
|
|
4360
4430
|
abort: (messageId) => sendClientMsgWithResponse({ cmd: "abort-ai", messageId }),
|
|
4431
|
+
setToolResult,
|
|
4361
4432
|
getStatus: () => managedSocket.getStatus(),
|
|
4362
4433
|
signals: {
|
|
4363
4434
|
chats\u03A3: context.chatsStore.chats\u03A3,
|
|
4364
4435
|
getChatMessagesForBranch\u03A3: context.messagesStore.getChatMessagesForBranch\u03A3,
|
|
4365
|
-
|
|
4366
|
-
getMessagesForChat\u03A3: context.messagesStore.getMessagesForChat\u03A3
|
|
4436
|
+
getTool\u03A3: context.toolsStore.getTool\u03A3
|
|
4367
4437
|
},
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4438
|
+
getChatById: context.chatsStore.getChatById,
|
|
4439
|
+
registerKnowledgeLayer,
|
|
4440
|
+
deregisterKnowledgeLayer,
|
|
4441
|
+
updateKnowledge,
|
|
4442
|
+
registerTool: context.toolsStore.registerTool
|
|
4371
4443
|
},
|
|
4372
4444
|
kInternal,
|
|
4373
4445
|
{ enumerable: false }
|
|
@@ -10531,6 +10603,7 @@ export {
|
|
|
10531
10603
|
createManagedPool,
|
|
10532
10604
|
createNotificationSettings,
|
|
10533
10605
|
createThreadId,
|
|
10606
|
+
defineAiTool,
|
|
10534
10607
|
deprecate,
|
|
10535
10608
|
deprecateIf,
|
|
10536
10609
|
detectDupes,
|