@xpert-ai/chatkit-types 0.6.2 → 0.7.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/dist/index.cjs +239 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +238 -2
- package/dist/index.js +240 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { CHAT_EVENT_TYPE_FOLLOW_UP_CONSUMED, ChatMessageEventTypeEnum, ChatMessageStepCategory, ChatMessageTypeEnum, STATE_VARIABLE_HUMAN } from "./constants.js";
|
|
2
2
|
import "@langchain/core/messages/tool";
|
|
3
|
+
function isApprovalHostReference(value) {
|
|
4
|
+
return !!value && typeof value === "object" && "kind" in value && typeof value.kind === "string" && value.kind.length > 0 && "id" in value && typeof value.id === "string" && value.id.length > 0 && "expiresAt" in value && typeof value.expiresAt === "number" && Number.isFinite(value.expiresAt);
|
|
5
|
+
}
|
|
3
6
|
function isLocalizedText(value) {
|
|
4
7
|
return typeof value === "string" || !!value && typeof value === "object" && !Array.isArray(value) && Object.values(value).every((item) => typeof item === "string" || item === void 0);
|
|
5
8
|
}
|
|
@@ -129,9 +132,7 @@ function normalizeHITLRequest(value) {
|
|
|
129
132
|
const normalizedActionRequests = actionRequests.map(
|
|
130
133
|
normalizeHITLActionRequest
|
|
131
134
|
);
|
|
132
|
-
const normalizedReviewConfigs = reviewConfigs.map(
|
|
133
|
-
normalizeHITLReviewConfig
|
|
134
|
-
);
|
|
135
|
+
const normalizedReviewConfigs = reviewConfigs.map(normalizeHITLReviewConfig);
|
|
135
136
|
if (normalizedActionRequests.some((request) => request === null) || normalizedReviewConfigs.some((config2) => config2 === null)) {
|
|
136
137
|
return null;
|
|
137
138
|
}
|
|
@@ -139,6 +140,12 @@ function normalizeHITLRequest(value) {
|
|
|
139
140
|
actionRequests: normalizedActionRequests,
|
|
140
141
|
reviewConfigs: normalizedReviewConfigs
|
|
141
142
|
};
|
|
143
|
+
if (value.host !== void 0) {
|
|
144
|
+
if (!isApprovalHostReference(value.host)) return null;
|
|
145
|
+
normalizedRequest.host = value.host;
|
|
146
|
+
}
|
|
147
|
+
if (typeof value.toolCallId === "string")
|
|
148
|
+
normalizedRequest.toolCallId = value.toolCallId;
|
|
142
149
|
const elicitation = normalizeHITLMCPElicitation(value.elicitation);
|
|
143
150
|
if (!elicitation || normalizedRequest.actionRequests.length !== 1) {
|
|
144
151
|
return normalizedRequest;
|
|
@@ -603,6 +610,222 @@ function getMessageSkillUsages(message) {
|
|
|
603
610
|
}
|
|
604
611
|
const TOOL_OUTPUT_PRESENTATION_TYPE = "xpert.tool-output";
|
|
605
612
|
const TOOL_OUTPUT_PRESENTATION_VERSION = 1;
|
|
613
|
+
function parseFileActivityContent(value) {
|
|
614
|
+
if (!value || typeof value !== "object") return null;
|
|
615
|
+
const part = value;
|
|
616
|
+
if (part.type !== "file_activity" || typeof part.id !== "string" || !part.id || !part.data || typeof part.data !== "object") return null;
|
|
617
|
+
const data = part.data;
|
|
618
|
+
if (data.version !== 1 || data.receiptId !== part.id || typeof data.toolCallId !== "string" || !data.toolCallId || typeof data.updatedAt !== "string" || !Number.isFinite(Date.parse(data.updatedAt))) return null;
|
|
619
|
+
const base = { version: 1, receiptId: part.id, toolCallId: data.toolCallId, updatedAt: data.updatedAt };
|
|
620
|
+
let receipt;
|
|
621
|
+
if (data.kind === "changes" && ["bounded", "partial", "unavailable"].includes(data.coverage) && Array.isArray(data.fileChanges)) {
|
|
622
|
+
const fileChanges = normalizeFileChanges(data.fileChanges);
|
|
623
|
+
if (fileChanges.length !== data.fileChanges.length) return null;
|
|
624
|
+
receipt = { ...base, kind: "changes", coverage: data.coverage, fileChanges };
|
|
625
|
+
} else if (data.kind === "delivery" && data.status === "success" && Array.isArray(data.outputs)) {
|
|
626
|
+
const outputs = normalizeFileOutputs(data.outputs);
|
|
627
|
+
if (outputs.length !== data.outputs.length) return null;
|
|
628
|
+
receipt = { ...base, kind: "delivery", status: "success", outputs };
|
|
629
|
+
} else if (data.kind === "delivery" && data.status === "error" && typeof data.error === "string") {
|
|
630
|
+
receipt = { ...base, kind: "delivery", status: "error", error: data.error };
|
|
631
|
+
} else return null;
|
|
632
|
+
return {
|
|
633
|
+
id: part.id,
|
|
634
|
+
type: "file_activity",
|
|
635
|
+
data: receipt,
|
|
636
|
+
...typeof part.messageId === "string" ? { messageId: part.messageId } : {},
|
|
637
|
+
...typeof part.executionId === "string" ? { executionId: part.executionId } : {},
|
|
638
|
+
...typeof part.agentKey === "string" ? { agentKey: part.agentKey } : {},
|
|
639
|
+
...typeof part.parentExecutionId === "string" ? { parentExecutionId: part.parentExecutionId } : {},
|
|
640
|
+
...typeof part.runId === "string" ? { runId: part.runId } : {}
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
function getLegacyFileActivityContribution(value) {
|
|
644
|
+
var _a;
|
|
645
|
+
if (!value || typeof value !== "object") return null;
|
|
646
|
+
const part = value;
|
|
647
|
+
const step = part.type === "component" ? part.data : value;
|
|
648
|
+
if (!step || typeof step !== "object") return null;
|
|
649
|
+
const summary = step.taskSummary ?? ((_a = step._meta) == null ? void 0 : _a["xpertai/taskSummary"]);
|
|
650
|
+
const id = part.id ?? step.id;
|
|
651
|
+
return (summary == null ? void 0 : summary.version) === 1 && summary.fileActivityVersion === 1 && typeof summary.fileActivityToolCallId === "string" && Boolean(summary.fileActivityToolCallId) && typeof id === "string" && id !== summary.fileActivityToolCallId ? summary : null;
|
|
652
|
+
}
|
|
653
|
+
function isFileActivityContent(value) {
|
|
654
|
+
return Boolean(value && typeof value === "object" && "type" in value && value.type === "file_activity") || getLegacyFileActivityContribution(value) !== null;
|
|
655
|
+
}
|
|
656
|
+
function getFileActivityContribution(value) {
|
|
657
|
+
const part = parseFileActivityContent(value);
|
|
658
|
+
if (!part) return getLegacyFileActivityContribution(value);
|
|
659
|
+
const receipt = part.data;
|
|
660
|
+
return {
|
|
661
|
+
version: 1,
|
|
662
|
+
fileActivityVersion: 1,
|
|
663
|
+
fileActivityToolCallId: receipt.toolCallId,
|
|
664
|
+
...receipt.kind === "changes" ? { fileChanges: receipt.fileChanges, fileChangeCoverage: receipt.coverage } : receipt.status === "success" ? { outputs: receipt.outputs } : {}
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
function upsertFileActivityContent(content, receipt) {
|
|
668
|
+
const index = content.findIndex((item) => {
|
|
669
|
+
var _a;
|
|
670
|
+
return ((_a = parseFileActivityContent(item)) == null ? void 0 : _a.id) === receipt.id;
|
|
671
|
+
});
|
|
672
|
+
if (index < 0) return [...content, receipt];
|
|
673
|
+
const previous = parseFileActivityContent(content[index]);
|
|
674
|
+
if (previous && Date.parse(previous.data.updatedAt) >= Date.parse(receipt.data.updatedAt)) return content;
|
|
675
|
+
return content.map((item, position) => position === index ? receipt : item);
|
|
676
|
+
}
|
|
677
|
+
function fileChangeRangeKey(resource) {
|
|
678
|
+
return JSON.stringify([resource.first.artifactId, resource.first.artifactVersionId, resource.last.artifactId, resource.last.artifactVersionId]);
|
|
679
|
+
}
|
|
680
|
+
const writeTools = /* @__PURE__ */ new Set(["sandbox_write_file", "sandbox_append_file", "sandbox_edit_file", "sandbox_multi_edit_file"]);
|
|
681
|
+
function normalizeFileChanges(value) {
|
|
682
|
+
if (!Array.isArray(value)) return [];
|
|
683
|
+
return value.filter((item) => {
|
|
684
|
+
if (!item || typeof item !== "object") return false;
|
|
685
|
+
const change = item;
|
|
686
|
+
return typeof change.id === "string" && typeof change.workspacePath === "string" && typeof change.title === "string" && ["added", "modified", "deleted", "unknown"].includes(change.operation ?? "") && ["observed", "legacy"].includes(change.coverage ?? "") && (!change.resource || change.resource.type === "file_change" && validVersion(change.resource.first) && validVersion(change.resource.last)) && validRevision(change.before) && validRevision(change.after);
|
|
687
|
+
}).map(({ id, title, workspacePath, operation, before, after, resource, coverage, messageId, startedAt, updatedAt }) => ({
|
|
688
|
+
id,
|
|
689
|
+
title,
|
|
690
|
+
workspacePath,
|
|
691
|
+
operation,
|
|
692
|
+
before: compactRevision(before),
|
|
693
|
+
after: compactRevision(after),
|
|
694
|
+
resource,
|
|
695
|
+
coverage,
|
|
696
|
+
messageId,
|
|
697
|
+
startedAt,
|
|
698
|
+
updatedAt
|
|
699
|
+
}));
|
|
700
|
+
}
|
|
701
|
+
function compactRevision(value) {
|
|
702
|
+
return value ? { sha256: value.sha256, size: value.size } : value;
|
|
703
|
+
}
|
|
704
|
+
function normalizeFileOutputs(value) {
|
|
705
|
+
if (!Array.isArray(value)) return [];
|
|
706
|
+
return value.flatMap((item) => {
|
|
707
|
+
if (!item || typeof item !== "object") return [];
|
|
708
|
+
const output = compactOutput(item);
|
|
709
|
+
return output ? [output] : [];
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
function compactOutput(value) {
|
|
713
|
+
if (!value || typeof value.id !== "string" || typeof value.title !== "string" || !["file", "image", "document", "spreadsheet", "presentation", "site", "url", "mcp_app"].includes(value.kind) || value.status !== void 0 && value.status !== "success") return null;
|
|
714
|
+
const ref = value.resource;
|
|
715
|
+
const resource = (ref == null ? void 0 : ref.type) === "artifact" && typeof ref.artifactId === "string" ? { type: "artifact", artifactId: ref.artifactId, ...typeof ref.artifactVersionId === "string" ? { artifactVersionId: ref.artifactVersionId } : {} } : (ref == null ? void 0 : ref.type) === "workspace_file" && typeof ref.workspacePath === "string" ? { type: "workspace_file", workspacePath: ref.workspacePath, fileAssetId: ref.fileAssetId, storageFileId: ref.storageFileId } : (ref == null ? void 0 : ref.type) === "url" && typeof ref.url === "string" ? { type: "url", url: ref.url } : void 0;
|
|
716
|
+
if (!resource) return null;
|
|
717
|
+
const { id, kind, title, description, status, origin, workspacePath, mimeType, size, sha256, messageId, updatedAt } = value;
|
|
718
|
+
return { id, kind, title, description, status, resource, origin, workspacePath, mimeType, size, sha256, messageId, updatedAt };
|
|
719
|
+
}
|
|
720
|
+
function validVersion(value) {
|
|
721
|
+
return Boolean(value && typeof value.artifactId === "string" && typeof value.artifactVersionId === "string");
|
|
722
|
+
}
|
|
723
|
+
function validRevision(value) {
|
|
724
|
+
return value == null || typeof value.sha256 === "string" && /^[a-f0-9]{64}$/.test(value.sha256) && Number.isSafeInteger(value.size) && value.size >= 0;
|
|
725
|
+
}
|
|
726
|
+
function mergeFileChanges(items) {
|
|
727
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
728
|
+
for (const item of [...items].sort((a, b) => (a.startedAt ?? a.updatedAt ?? "").localeCompare(b.startedAt ?? b.updatedAt ?? ""))) {
|
|
729
|
+
const previous = byPath.get(item.workspacePath);
|
|
730
|
+
if (!previous || previous.coverage === "legacy") {
|
|
731
|
+
byPath.set(item.workspacePath, item);
|
|
732
|
+
continue;
|
|
733
|
+
}
|
|
734
|
+
if (item.coverage === "legacy") continue;
|
|
735
|
+
const latest = (item.updatedAt ?? "") >= (previous.updatedAt ?? "") ? item : previous;
|
|
736
|
+
const earliest = (item.startedAt ?? item.updatedAt ?? "") < (previous.startedAt ?? previous.updatedAt ?? "") ? item : previous;
|
|
737
|
+
const before = earliest.before;
|
|
738
|
+
const after = latest.after;
|
|
739
|
+
byPath.set(item.workspacePath, {
|
|
740
|
+
...latest,
|
|
741
|
+
before,
|
|
742
|
+
after,
|
|
743
|
+
startedAt: earliest.startedAt ?? earliest.updatedAt,
|
|
744
|
+
operation: before === null ? "added" : after === null ? "deleted" : "modified",
|
|
745
|
+
resource: earliest.resource && latest.resource ? { type: "file_change", first: earliest.resource.first, last: latest.resource.last } : latest.resource
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
return [...byPath.values()].filter((item) => {
|
|
749
|
+
var _a, _b;
|
|
750
|
+
return item.coverage === "legacy" || ((_a = item.before) == null ? void 0 : _a.sha256) !== ((_b = item.after) == null ? void 0 : _b.sha256);
|
|
751
|
+
}).sort((a, b) => (b.updatedAt ?? "").localeCompare(a.updatedAt ?? ""));
|
|
752
|
+
}
|
|
753
|
+
function projectMessageFileActivity(message, contribution) {
|
|
754
|
+
var _a, _b, _c, _d, _e;
|
|
755
|
+
const parts = Array.isArray(message.content) ? message.content : [];
|
|
756
|
+
const observed = [];
|
|
757
|
+
const legacyChanges = [];
|
|
758
|
+
const legacyOutputIds = /* @__PURE__ */ new Set();
|
|
759
|
+
const date = message.updatedAt ?? message.createdAt;
|
|
760
|
+
const updatedAt = date instanceof Date ? date.toISOString() : date;
|
|
761
|
+
const observedToolCalls = new Set(parts.flatMap((part) => {
|
|
762
|
+
var _a2, _b2, _c2;
|
|
763
|
+
const summary = getFileActivityContribution(part) ?? ((_a2 = part.data) == null ? void 0 : _a2.taskSummary) ?? ((_c2 = (_b2 = part.data) == null ? void 0 : _b2._meta) == null ? void 0 : _c2["xpertai/taskSummary"]);
|
|
764
|
+
return (summary == null ? void 0 : summary.fileActivityToolCallId) ? [summary.fileActivityToolCallId] : [];
|
|
765
|
+
}));
|
|
766
|
+
for (const part of parts) {
|
|
767
|
+
const receipt = getFileActivityContribution(part);
|
|
768
|
+
if (receipt) {
|
|
769
|
+
observed.push(receipt);
|
|
770
|
+
continue;
|
|
771
|
+
}
|
|
772
|
+
if ((part == null ? void 0 : part.type) !== "component" || !part.data) continue;
|
|
773
|
+
const data = part.data;
|
|
774
|
+
const explicit = data.taskSummary ?? ((_a = data._meta) == null ? void 0 : _a["xpertai/taskSummary"]);
|
|
775
|
+
if ((explicit == null ? void 0 : explicit.version) === 1) observed.push(explicit);
|
|
776
|
+
if (!writeTools.has(data.tool ?? "") || data.status !== "success") continue;
|
|
777
|
+
const path = (_b = data.input) == null ? void 0 : _b.file_path;
|
|
778
|
+
if (typeof path !== "string" || !path || path.startsWith("/") || path.split("/").includes("..")) continue;
|
|
779
|
+
legacyOutputIds.add(`workspace-file:${path}`);
|
|
780
|
+
if ((explicit == null ? void 0 : explicit.fileActivityVersion) === 1 || part.id && observedToolCalls.has(part.id)) continue;
|
|
781
|
+
legacyChanges.push({ id: `file-change:${path}`, title: path, workspacePath: path, operation: "unknown", coverage: "legacy", messageId: message.id, updatedAt });
|
|
782
|
+
}
|
|
783
|
+
if (!observed.length && !legacyOutputIds.size && !((_c = contribution.outputs) == null ? void 0 : _c.length) && !((_d = contribution.fileChanges) == null ? void 0 : _d.length)) return contribution;
|
|
784
|
+
const outputs = [...contribution.outputs ?? [], ...observed.flatMap((item) => item.outputs ?? [])];
|
|
785
|
+
const byId = /* @__PURE__ */ new Map();
|
|
786
|
+
for (const raw of outputs) {
|
|
787
|
+
const output = compactOutput(raw);
|
|
788
|
+
if (!output) continue;
|
|
789
|
+
if (legacyOutputIds.has(output.id) && output.origin !== "tool" && output.origin !== "integration") continue;
|
|
790
|
+
if ((((_e = byId.get(output.id)) == null ? void 0 : _e.updatedAt) ?? "") > (output.updatedAt ?? updatedAt ?? "")) continue;
|
|
791
|
+
byId.set(output.id, { ...output, origin: output.origin ?? "legacy", messageId: message.id ?? output.messageId, updatedAt: output.updatedAt ?? updatedAt });
|
|
792
|
+
}
|
|
793
|
+
const changes = mergeFileChanges([
|
|
794
|
+
...legacyChanges,
|
|
795
|
+
...normalizeFileChanges(contribution.fileChanges),
|
|
796
|
+
...observed.flatMap((item) => normalizeFileChanges(item.fileChanges))
|
|
797
|
+
].map((item) => ({ ...item, messageId: message.id ?? item.messageId })));
|
|
798
|
+
const coverage = [contribution.fileChangeCoverage, ...observed.map((item) => item.fileChangeCoverage)];
|
|
799
|
+
const fileChangeCoverage = coverage.includes("unavailable") ? "unavailable" : coverage.includes("partial") ? "partial" : coverage.includes("bounded") ? "bounded" : void 0;
|
|
800
|
+
return { ...contribution, fileActivityVersion: 1, fileChangeCoverage, outputs: [...byId.values()], fileChanges: changes };
|
|
801
|
+
}
|
|
802
|
+
function parseFileChangeReport(value) {
|
|
803
|
+
if (!value || typeof value !== "object") return null;
|
|
804
|
+
const report = value;
|
|
805
|
+
const revision = (item) => item === null || Boolean(item && validRevision(item) && (item.text === void 0 || typeof item.text === "string" && item.text.length <= 32768));
|
|
806
|
+
return report.schema === "xpert.file-change.v1" && typeof report.workspacePath === "string" && revision(report.before) && revision(report.after) ? report : null;
|
|
807
|
+
}
|
|
808
|
+
const MAX_DIFF_CELLS = 4e6;
|
|
809
|
+
function countFileChangeLines(report) {
|
|
810
|
+
var _a, _b;
|
|
811
|
+
if (report.before && report.before.text === void 0 || report.after && report.after.text === void 0) return { status: "unavailable" };
|
|
812
|
+
const lines = (text) => text ? text.replace(/\r\n/g, "\n").replace(/\n$/, "").split("\n") : [];
|
|
813
|
+
const before = lines(((_a = report.before) == null ? void 0 : _a.text) ?? ""), after = lines(((_b = report.after) == null ? void 0 : _b.text) ?? "");
|
|
814
|
+
let start = 0, endBefore = before.length, endAfter = after.length;
|
|
815
|
+
while (start < endBefore && start < endAfter && before[start] === after[start]) start++;
|
|
816
|
+
while (endBefore > start && endAfter > start && before[endBefore - 1] === after[endAfter - 1]) {
|
|
817
|
+
endBefore--;
|
|
818
|
+
endAfter--;
|
|
819
|
+
}
|
|
820
|
+
const n = endBefore - start, m = endAfter - start;
|
|
821
|
+
if (n * m > MAX_DIFF_CELLS) return { status: "unavailable" };
|
|
822
|
+
let previous = new Uint32Array(m + 1), current = new Uint32Array(m + 1);
|
|
823
|
+
for (let i = 0; i < n; i++) {
|
|
824
|
+
for (let j = 0; j < m; j++) current[j + 1] = before[start + i] === after[start + j] ? previous[j] + 1 : Math.max(previous[j + 1], current[j]);
|
|
825
|
+
[previous, current] = [current, previous];
|
|
826
|
+
}
|
|
827
|
+
return { status: "ready", added: m - previous[m], removed: n - previous[m] };
|
|
828
|
+
}
|
|
606
829
|
export {
|
|
607
830
|
CHATKIT_TASK_SUMMARY_OPEN_RESOURCE_EFFECT,
|
|
608
831
|
CHAT_EVENT_TYPE_FOLLOW_UP_CONSUMED,
|
|
@@ -624,12 +847,18 @@ export {
|
|
|
624
847
|
TOOL_OUTPUT_PRESENTATION_VERSION,
|
|
625
848
|
chatSkillUsageKey,
|
|
626
849
|
clampPetPosition,
|
|
850
|
+
countFileChangeLines,
|
|
851
|
+
fileChangeRangeKey,
|
|
852
|
+
getFileActivityContribution,
|
|
853
|
+
getLegacyFileActivityContribution,
|
|
627
854
|
getMessageSkillUsages,
|
|
628
855
|
getPinnedPetPosition,
|
|
856
|
+
isApprovalHostReference,
|
|
629
857
|
isClientToolInterrupt,
|
|
630
858
|
isClientToolInterruptPayload,
|
|
631
859
|
isClientToolInterruptTask,
|
|
632
860
|
isClientToolRequest,
|
|
861
|
+
isFileActivityContent,
|
|
633
862
|
isHITLDecisionType,
|
|
634
863
|
isHITLInterrupt,
|
|
635
864
|
isHITLInterruptPayload,
|
|
@@ -645,15 +874,22 @@ export {
|
|
|
645
874
|
isToolCallInterruptTask,
|
|
646
875
|
isToolCallRequest,
|
|
647
876
|
mergeChatSkillUsages,
|
|
877
|
+
mergeFileChanges,
|
|
648
878
|
mergePetSpriteAtlas,
|
|
649
879
|
normalizeBoundsPadding,
|
|
650
880
|
normalizeChatSkillUsages,
|
|
881
|
+
normalizeFileChanges,
|
|
882
|
+
normalizeFileOutputs,
|
|
651
883
|
normalizeHITLRequest,
|
|
652
884
|
normalizePetOptions,
|
|
653
885
|
normalizeRequestLanguage,
|
|
654
886
|
normalizeThreadReference,
|
|
887
|
+
parseFileActivityContent,
|
|
888
|
+
parseFileChangeReport,
|
|
655
889
|
petSpriteAtlas,
|
|
890
|
+
projectMessageFileActivity,
|
|
656
891
|
resolveLocalizedText,
|
|
657
|
-
resolvePetCharacter
|
|
892
|
+
resolvePetCharacter,
|
|
893
|
+
upsertFileActivityContent
|
|
658
894
|
};
|
|
659
895
|
//# sourceMappingURL=index.js.map
|