@llblab/pi-kit 0.26.0 → 0.27.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/BACKLOG.md +2 -2
- package/CHANGELOG.md +5 -0
- package/README.md +4 -4
- package/node_modules/@llblab/pi-state-flow/AGENTS.md +1 -1
- package/node_modules/@llblab/pi-state-flow/BACKLOG.md +12 -5
- package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +9 -0
- package/node_modules/@llblab/pi-state-flow/README.md +116 -34
- package/node_modules/@llblab/pi-state-flow/dist/lib/acquisition.d.ts +24 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/acquisition.js +80 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/compaction.d.ts +17 -0
- package/node_modules/@llblab/pi-state-flow/dist/lib/compaction.js +40 -0
- package/node_modules/@llblab/pi-state-flow/dist/lib/extension.js +149 -298
- package/node_modules/@llblab/pi-state-flow/dist/lib/git.d.ts +29 -0
- package/node_modules/@llblab/pi-state-flow/dist/lib/git.js +58 -0
- package/node_modules/@llblab/pi-state-flow/dist/lib/operation.d.ts +37 -0
- package/node_modules/@llblab/pi-state-flow/dist/lib/operation.js +59 -0
- package/node_modules/@llblab/pi-state-flow/dist/lib/ownership.d.ts +31 -0
- package/node_modules/@llblab/pi-state-flow/dist/lib/ownership.js +117 -0
- package/node_modules/@llblab/pi-state-flow/dist/lib/protocol.js +7 -7
- package/node_modules/@llblab/pi-state-flow/dist/lib/query.js +1 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/status.d.ts +2 -0
- package/node_modules/@llblab/pi-state-flow/dist/lib/status.js +28 -0
- package/node_modules/@llblab/pi-state-flow/dist/lib/transition.js +6 -1
- package/node_modules/@llblab/pi-state-flow/dist/package.json +1 -1
- package/node_modules/@llblab/pi-state-flow/dist/skills/state-flow-guide/SKILL.md +14 -6
- package/node_modules/@llblab/pi-state-flow/dist/skills/state-flow-memory/SKILL.md +2 -2
- package/node_modules/@llblab/pi-state-flow/docs/README.md +19 -9
- package/node_modules/@llblab/pi-state-flow/docs/agent-contract-relocation.md +4 -4
- package/node_modules/@llblab/pi-state-flow/docs/architecture.md +644 -91
- package/node_modules/@llblab/pi-state-flow/docs/compatibility.md +116 -37
- package/node_modules/@llblab/pi-state-flow/docs/filesystem-recovery.md +118 -21
- package/node_modules/@llblab/pi-state-flow/docs/fork-contract.md +68 -8
- package/node_modules/@llblab/pi-state-flow/docs/lazy-state.md +88 -14
- package/node_modules/@llblab/pi-state-flow/docs/performance.md +83 -66
- package/node_modules/@llblab/pi-state-flow/docs/temporal-acceptance.md +391 -62
- package/node_modules/@llblab/pi-state-flow/docs/usage.md +317 -62
- package/node_modules/@llblab/pi-state-flow/lib/acquisition.ts +85 -1
- package/node_modules/@llblab/pi-state-flow/lib/compaction.ts +47 -0
- package/node_modules/@llblab/pi-state-flow/lib/extension.ts +161 -295
- package/node_modules/@llblab/pi-state-flow/lib/git.ts +63 -0
- package/node_modules/@llblab/pi-state-flow/lib/operation.ts +75 -0
- package/node_modules/@llblab/pi-state-flow/lib/ownership.ts +120 -0
- package/node_modules/@llblab/pi-state-flow/lib/protocol.ts +7 -8
- package/node_modules/@llblab/pi-state-flow/lib/query.ts +1 -1
- package/node_modules/@llblab/pi-state-flow/lib/runtime.ts +1 -1
- package/node_modules/@llblab/pi-state-flow/lib/snapshot.ts +1 -2
- package/node_modules/@llblab/pi-state-flow/lib/status.ts +29 -0
- package/node_modules/@llblab/pi-state-flow/lib/transition.ts +5 -1
- package/node_modules/@llblab/pi-state-flow/package.json +1 -1
- package/node_modules/@llblab/pi-state-flow/skills/state-flow-guide/SKILL.md +14 -6
- package/node_modules/@llblab/pi-state-flow/skills/state-flow-memory/SKILL.md +2 -2
- package/node_modules/@llblab/pi-telegram/BACKLOG.md +1 -0
- package/node_modules/@llblab/pi-telegram/CHANGELOG.md +10 -0
- package/node_modules/@llblab/pi-telegram/README.md +1 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/bindings.d.ts +4 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/bindings.js +16 -12
- package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.d.ts +1 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.js +7 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/commands.d.ts +12 -3
- package/node_modules/@llblab/pi-telegram/dist/lib/commands.js +137 -83
- package/node_modules/@llblab/pi-telegram/dist/lib/extension.js +26 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/lifecycle.d.ts +57 -2
- package/node_modules/@llblab/pi-telegram/dist/lib/lifecycle.js +109 -4
- package/node_modules/@llblab/pi-telegram/dist/lib/model.js +2 -4
- package/node_modules/@llblab/pi-telegram/dist/lib/status.d.ts +3 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/status.js +31 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/sync.js +4 -4
- package/node_modules/@llblab/pi-telegram/dist/lib/threads.d.ts +1 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/threads.js +17 -4
- package/node_modules/@llblab/pi-telegram/dist/lib/workspace-retirement.d.ts +2 -2
- package/node_modules/@llblab/pi-telegram/dist/lib/workspace-retirement.js +48 -12
- package/node_modules/@llblab/pi-telegram/dist/package.json +1 -1
- package/node_modules/@llblab/pi-telegram/docs/architecture.md +6 -5
- package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +2 -0
- package/node_modules/@llblab/pi-telegram/docs/public-api.md +2 -2
- package/node_modules/@llblab/pi-telegram/docs/ui-style.md +4 -0
- package/node_modules/@llblab/pi-telegram/lib/bindings.ts +17 -10
- package/node_modules/@llblab/pi-telegram/lib/bus-follower.ts +8 -2
- package/node_modules/@llblab/pi-telegram/lib/commands.ts +135 -97
- package/node_modules/@llblab/pi-telegram/lib/extension.ts +25 -0
- package/node_modules/@llblab/pi-telegram/lib/lifecycle.ts +140 -4
- package/node_modules/@llblab/pi-telegram/lib/model.ts +2 -4
- package/node_modules/@llblab/pi-telegram/lib/status.ts +30 -1
- package/node_modules/@llblab/pi-telegram/lib/sync.ts +4 -4
- package/node_modules/@llblab/pi-telegram/lib/threads.ts +21 -3
- package/node_modules/@llblab/pi-telegram/lib/workspace-retirement.ts +46 -13
- package/node_modules/@llblab/pi-telegram/package.json +1 -1
- package/package.json +3 -3
|
@@ -229,6 +229,7 @@ export interface TelegramThreadPendingProvision {
|
|
|
229
229
|
owner: "leader" | "manual-follower";
|
|
230
230
|
instanceId: string;
|
|
231
231
|
profileKey?: string;
|
|
232
|
+
workspaceBindingKey?: string;
|
|
232
233
|
status?: "in-flight" | "ambiguous";
|
|
233
234
|
threadName?: string;
|
|
234
235
|
displayTitle?: string;
|
|
@@ -1528,6 +1529,9 @@ function normalizePendingProvision(
|
|
|
1528
1529
|
...(record.status === "in-flight" || record.status === "ambiguous"
|
|
1529
1530
|
? { status: record.status }
|
|
1530
1531
|
: {}),
|
|
1532
|
+
...(typeof record.workspaceBindingKey === "string"
|
|
1533
|
+
? { workspaceBindingKey: record.workspaceBindingKey }
|
|
1534
|
+
: {}),
|
|
1531
1535
|
...(typeof record.threadName === "string"
|
|
1532
1536
|
? { threadName: record.threadName }
|
|
1533
1537
|
: {}),
|
|
@@ -4919,6 +4923,13 @@ export function createTelegramTopicTargetProvisioner(
|
|
|
4919
4923
|
pending.profileKey === request.profileKey ||
|
|
4920
4924
|
pending.instanceId === request.instanceId,
|
|
4921
4925
|
);
|
|
4926
|
+
const pendingTarget = pendingForRequest?.target;
|
|
4927
|
+
if (pendingForRequest && request.workspaceBindingKey &&
|
|
4928
|
+
pendingForRequest.workspaceBindingKey !== request.workspaceBindingKey &&
|
|
4929
|
+
!(pendingTarget && deps.store.listWorkspaceBindings().some((binding) =>
|
|
4930
|
+
binding.bindingKey === request.workspaceBindingKey && targetMatches(binding.target, pendingTarget)))) {
|
|
4931
|
+
throw new Error("Telegram unfinished Thread creation does not match this session binding.");
|
|
4932
|
+
}
|
|
4922
4933
|
if (pendingForRequest?.target) {
|
|
4923
4934
|
const target = pendingForRequest.target;
|
|
4924
4935
|
const observation = deps.store.listSyncObservations().find((entry) =>
|
|
@@ -4933,8 +4944,13 @@ export function createTelegramTopicTargetProvisioner(
|
|
|
4933
4944
|
pendingForRequest = undefined;
|
|
4934
4945
|
}
|
|
4935
4946
|
}
|
|
4947
|
+
const matchesWorkspace = (target: TelegramTarget): boolean =>
|
|
4948
|
+
!request.workspaceBindingKey ||
|
|
4949
|
+
deps.store.listWorkspaceBindings().some((binding) =>
|
|
4950
|
+
binding.bindingKey === request.workspaceBindingKey && targetMatches(binding.target, target)) ||
|
|
4951
|
+
(!!pendingForRequest?.target && targetMatches(pendingForRequest.target, target));
|
|
4936
4952
|
const existing = deps.store.getByProfileKey(request.profileKey);
|
|
4937
|
-
if (existing && isCurrentThreadRecord(existing)) {
|
|
4953
|
+
if (existing && isCurrentThreadRecord(existing) && matchesWorkspace(existing.target)) {
|
|
4938
4954
|
const slot = existing.slot ?? deps.store.allocateSlot(request.profileKey);
|
|
4939
4955
|
if (!slot) {
|
|
4940
4956
|
throw new TelegramWorkspaceSlotUnavailableError();
|
|
@@ -5017,7 +5033,7 @@ export function createTelegramTopicTargetProvisioner(
|
|
|
5017
5033
|
const activeForInstance = deps.store.getActiveByInstanceId(
|
|
5018
5034
|
request.instanceId,
|
|
5019
5035
|
);
|
|
5020
|
-
if (activeForInstance) {
|
|
5036
|
+
if (activeForInstance && matchesWorkspace(activeForInstance.target)) {
|
|
5021
5037
|
if (!activeForInstance.slot) {
|
|
5022
5038
|
throw new Error("Telegram Workspace slot reservation is unavailable.");
|
|
5023
5039
|
}
|
|
@@ -5055,7 +5071,7 @@ export function createTelegramTopicTargetProvisioner(
|
|
|
5055
5071
|
getNextTelegramThreadNamePaletteSlot(deps.store.list(), undefined) ??
|
|
5056
5072
|
request.preferredSlot;
|
|
5057
5073
|
const slot =
|
|
5058
|
-
existing
|
|
5074
|
+
(existing && matchesWorkspace(existing.target) ? existing.slot : undefined) ??
|
|
5059
5075
|
deps.store.allocateSlot(
|
|
5060
5076
|
request.profileKey,
|
|
5061
5077
|
isManualFollowerRequest
|
|
@@ -5064,6 +5080,7 @@ export function createTelegramTopicTargetProvisioner(
|
|
|
5064
5080
|
(candidateThreadName ? undefined : identity?.slot) ??
|
|
5065
5081
|
preferredNameSlot),
|
|
5066
5082
|
request.workspaceBindingKey,
|
|
5083
|
+
{ excludeCurrentRecord: !!existing && !matchesWorkspace(existing.target) },
|
|
5067
5084
|
);
|
|
5068
5085
|
if (!slot) {
|
|
5069
5086
|
throw new TelegramWorkspaceSlotUnavailableError();
|
|
@@ -5107,6 +5124,7 @@ export function createTelegramTopicTargetProvisioner(
|
|
|
5107
5124
|
owner: pendingOwner,
|
|
5108
5125
|
instanceId: request.instanceId,
|
|
5109
5126
|
profileKey: request.profileKey,
|
|
5127
|
+
...(request.workspaceBindingKey ? { workspaceBindingKey: request.workspaceBindingKey } : {}),
|
|
5110
5128
|
threadName: requestThreadName,
|
|
5111
5129
|
...(displayTitle ? { displayTitle } : {}),
|
|
5112
5130
|
slot,
|
|
@@ -884,6 +884,7 @@ export async function executeTelegramWorkspaceRetirement(input: {
|
|
|
884
884
|
| "listWorkspaceRetirementIntents"
|
|
885
885
|
| "commitWorkspaceRetirement"
|
|
886
886
|
| "removeWorkspaceRetirementIntent"
|
|
887
|
+
| "markStaleByTarget"
|
|
887
888
|
| "persist"
|
|
888
889
|
>;
|
|
889
890
|
admission: Pick<
|
|
@@ -971,6 +972,12 @@ export async function executeTelegramWorkspaceRetirement(input: {
|
|
|
971
972
|
}
|
|
972
973
|
return { kind: "retained", reason: "stale-intent" };
|
|
973
974
|
}
|
|
975
|
+
if (fence?.phase === "commit-ready") {
|
|
976
|
+
// Exact confirmed absence retires any same-target routing record that
|
|
977
|
+
// survived the deletion attempt. The fence prevents replacement target
|
|
978
|
+
// publication while this stale local projection is removed.
|
|
979
|
+
input.store.markStaleByTarget(binding.target, "deleted");
|
|
980
|
+
}
|
|
974
981
|
const eligible = () => input.store.captureWorkspaceSlotOccupancy(
|
|
975
982
|
input.getExternalProtection,
|
|
976
983
|
{ expectedRetirement: input.intent },
|
|
@@ -1040,6 +1047,9 @@ export async function executeTelegramWorkspaceRetirement(input: {
|
|
|
1040
1047
|
fence = input.admission.confirmRetirementAbsence(fence);
|
|
1041
1048
|
}
|
|
1042
1049
|
if (!isCurrent()) return { kind: "retained", reason: "authority-changed" };
|
|
1050
|
+
if (fence.phase === "commit-ready") {
|
|
1051
|
+
input.store.markStaleByTarget(binding.target, "deleted");
|
|
1052
|
+
}
|
|
1043
1053
|
if (!eligible()) return { kind: "retained", reason: "protection-changed" };
|
|
1044
1054
|
if (!await input.store.commitWorkspaceRetirement(input.intent, isCurrent)) {
|
|
1045
1055
|
return { kind: "retained", reason: "commit-rejected" };
|
|
@@ -1212,7 +1222,7 @@ export type TelegramWorkspaceRetirementLifecycleResult =
|
|
|
1212
1222
|
export async function runTelegramWorkspaceRetirementLifecycle(input: {
|
|
1213
1223
|
store: TelegramWorkspaceRetirementPreparationDeps["store"] & Pick<
|
|
1214
1224
|
TelegramTopicTargetStore,
|
|
1215
|
-
"replaceWorkspaceRetirementIntent" | "commitWorkspaceRetirement"
|
|
1225
|
+
"replaceWorkspaceRetirementIntent" | "commitWorkspaceRetirement" | "markStaleByTarget"
|
|
1216
1226
|
>;
|
|
1217
1227
|
getExternalProtection: (
|
|
1218
1228
|
binding: TelegramWorkspaceThreadBinding,
|
|
@@ -1257,19 +1267,42 @@ export async function runTelegramWorkspaceRetirementLifecycle(input: {
|
|
|
1257
1267
|
});
|
|
1258
1268
|
}
|
|
1259
1269
|
if (intent) {
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1270
|
+
if (retainedFence && isTelegramWorkspaceRetirementFence(retainedFence) &&
|
|
1271
|
+
retainedFence.phase === "commit-ready" &&
|
|
1272
|
+
matchesTelegramWorkspaceRetirementFence(retainedFence, intent)) {
|
|
1273
|
+
const resumed = await input.runExclusive(async () => {
|
|
1274
|
+
const epoch = input.getLeaderEpoch();
|
|
1275
|
+
const profileKey = input.getProfileKey();
|
|
1276
|
+
const isCurrent = () => epoch !== undefined && input.getLeaderEpoch() === epoch &&
|
|
1277
|
+
input.getProfileKey() === profileKey && input.isCurrent?.() !== false;
|
|
1278
|
+
if (!isCurrent() || intent!.profileKey !== profileKey) return undefined;
|
|
1279
|
+
const intents = input.store.listWorkspaceRetirementIntents();
|
|
1280
|
+
const binding = input.store.listWorkspaceBindings().find(candidate =>
|
|
1281
|
+
candidate.bindingKey === intent!.binding.bindingKey);
|
|
1282
|
+
if (intents.length !== 1 || !isDeepStrictEqual(intents[0], intent) ||
|
|
1283
|
+
!binding || !isDeepStrictEqual(binding, intent.binding)) return undefined;
|
|
1284
|
+
if (intent!.leaderEpoch === epoch) return intent;
|
|
1285
|
+
const replacement = { ...intent!, leaderEpoch: epoch! };
|
|
1286
|
+
return await input.store.replaceWorkspaceRetirementIntent(intent!, replacement, isCurrent)
|
|
1287
|
+
? replacement : undefined;
|
|
1288
|
+
});
|
|
1289
|
+
if (!resumed) return { kind: "blocked", stage: "adoption", reason: "commit-rejected" };
|
|
1290
|
+
intent = resumed;
|
|
1291
|
+
} else {
|
|
1292
|
+
const adoption = await adoptTelegramWorkspaceRetirementIntent({
|
|
1293
|
+
store: input.store,
|
|
1294
|
+
intent,
|
|
1295
|
+
getExternalProtection: input.getExternalProtection,
|
|
1296
|
+
getLeaderEpoch: input.getLeaderEpoch,
|
|
1297
|
+
getProfileKey: input.getProfileKey,
|
|
1298
|
+
isCurrent: input.isCurrent,
|
|
1299
|
+
runExclusive: input.runExclusive,
|
|
1300
|
+
});
|
|
1301
|
+
if (adoption.kind !== "adopted") {
|
|
1302
|
+
return { kind: "blocked", stage: "adoption", reason: adoption.reason };
|
|
1303
|
+
}
|
|
1304
|
+
intent = adoption.intent;
|
|
1271
1305
|
}
|
|
1272
|
-
intent = adoption.intent;
|
|
1273
1306
|
} else {
|
|
1274
1307
|
const preparation = await prepareTelegramWorkspaceRetirement(
|
|
1275
1308
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llblab/pi-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"@llblab/pi-clean-room": "0.3.0",
|
|
47
47
|
"@llblab/pi-codex-usage": "0.12.0",
|
|
48
48
|
"@llblab/pi-grow-loop": "0.9.0",
|
|
49
|
-
"@llblab/pi-state-flow": "0.
|
|
50
|
-
"@llblab/pi-telegram": "0.51.
|
|
49
|
+
"@llblab/pi-state-flow": "0.25.0",
|
|
50
|
+
"@llblab/pi-telegram": "0.51.6",
|
|
51
51
|
"@llblab/skills": "1.15.0"
|
|
52
52
|
},
|
|
53
53
|
"bundledDependencies": [
|