@saleso.innovations/bridge 0.1.41 → 0.1.42
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/hermesForwarder.d.ts.map +1 -1
- package/dist/hermesForwarder.js +22 -4
- package/dist/hermesSessionDb.d.ts.map +1 -1
- package/dist/hermesSessionDb.js +4 -0
- package/dist/hermesStructuredContent.d.ts +8 -0
- package/dist/hermesStructuredContent.d.ts.map +1 -0
- package/dist/hermesStructuredContent.js +197 -0
- package/dist/hermesStructuredContent.test.d.ts +2 -0
- package/dist/hermesStructuredContent.test.d.ts.map +1 -0
- package/dist/hermesStructuredContent.test.js +15 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hermesForwarder.d.ts","sourceRoot":"","sources":["../src/hermesForwarder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAyB,eAAe,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"hermesForwarder.d.ts","sourceRoot":"","sources":["../src/hermesForwarder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAyB,eAAe,EAAE,MAAM,aAAa,CAAC;AAuBtF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAkBF,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,sBAA2B,GAAG;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf,CAUA;AAgID,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,CA0G9B;AA2BD,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,sBAA2B,IAC/D,SAAS,MAAM,EAAE,MAAM,eAAe,EAAE,OAAO,UAAU,KAAG,OAAO,CAAC,IAAI,CAAC,CAMxF"}
|
package/dist/hermesForwarder.js
CHANGED
|
@@ -7,6 +7,7 @@ import { getLatestTurnMessageIds, getSessionUsage, hermesStateDbExists } from ".
|
|
|
7
7
|
import { diffSkillsLearned, snapshotSkills } from "./skillLearnedDetector.js";
|
|
8
8
|
import { buildTurnActivity, createTurnActivityAccumulator, parseSseDataLines, processSseEventBlock, } from "./turnActivity.js";
|
|
9
9
|
import { parseMediaReferences, resolveMediaReferenceBytes, stripMediaReferences, } from "./hermesFiles.js";
|
|
10
|
+
import { looksLikeHermesStructuredStream, unwrapHermesStructuredContent, } from "./hermesStructuredContent.js";
|
|
10
11
|
function readHermesApiKeyFromEnvFile() {
|
|
11
12
|
const envPath = join(homedir(), ".hermes", ".env");
|
|
12
13
|
try {
|
|
@@ -183,6 +184,17 @@ export async function forwardToHermes(content, meta, reply, options = {}) {
|
|
|
183
184
|
const counters = { textSequence: 0, activitySequence: 0 };
|
|
184
185
|
const accumulator = createTurnActivityAccumulator();
|
|
185
186
|
let fullText = "";
|
|
187
|
+
let suppressStreamDeltas = false;
|
|
188
|
+
const streamingReply = {
|
|
189
|
+
delta(text, sequence) {
|
|
190
|
+
if (!suppressStreamDeltas) {
|
|
191
|
+
reply.delta(text, sequence);
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
activity: (activity) => reply.activity(activity),
|
|
195
|
+
complete: (...args) => reply.complete(...args),
|
|
196
|
+
failed: (failure) => reply.failed(failure),
|
|
197
|
+
};
|
|
186
198
|
while (true) {
|
|
187
199
|
const { done, value } = await reader.read();
|
|
188
200
|
if (done)
|
|
@@ -191,19 +203,25 @@ export async function forwardToHermes(content, meta, reply, options = {}) {
|
|
|
191
203
|
const { events, rest } = parseSseDataLines(buffer);
|
|
192
204
|
buffer = rest;
|
|
193
205
|
for (const eventBlock of events) {
|
|
194
|
-
processSseEventBlock(eventBlock,
|
|
206
|
+
processSseEventBlock(eventBlock, streamingReply, counters, accumulator, (delta) => {
|
|
195
207
|
fullText += delta;
|
|
208
|
+
if (!suppressStreamDeltas && looksLikeHermesStructuredStream(fullText)) {
|
|
209
|
+
suppressStreamDeltas = true;
|
|
210
|
+
}
|
|
196
211
|
});
|
|
197
212
|
}
|
|
198
213
|
}
|
|
199
214
|
if (!fullText.trim()) {
|
|
200
215
|
fullText = "(Hermes returned an empty response)";
|
|
201
|
-
|
|
202
|
-
|
|
216
|
+
if (!suppressStreamDeltas) {
|
|
217
|
+
reply.delta(fullText, counters.textSequence);
|
|
218
|
+
counters.textSequence += 1;
|
|
219
|
+
}
|
|
203
220
|
}
|
|
204
221
|
const mediaRefs = parseMediaReferences(fullText);
|
|
205
222
|
const attachments = mediaRefs.length > 0 ? await uploadMediaAttachments(meta.agentId, mediaRefs) : [];
|
|
206
|
-
const
|
|
223
|
+
const rawDisplayText = attachments.length > 0 ? stripMediaReferences(fullText, mediaRefs) : fullText.trim() || fullText;
|
|
224
|
+
const displayText = unwrapHermesStructuredContent(rawDisplayText);
|
|
207
225
|
const { assistantMessageId } = getLatestTurnMessageIds(resolvedSessionId);
|
|
208
226
|
const replyModel = resolveReplyModel(modelFromHeader, resolvedSessionId, model);
|
|
209
227
|
const turnActivity = buildTurnActivity(accumulator, replyModel);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hermesSessionDb.d.ts","sourceRoot":"","sources":["../src/hermesSessionDb.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hermesSessionDb.d.ts","sourceRoot":"","sources":["../src/hermesSessionDb.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AA4IF,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAapE;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAuBxF;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACxE,oBAAoB,EAAE,CAwCxB;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,GAChB;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,CAmCzD;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAMF,mFAAmF;AACnF,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAqBvE;AAcD,wBAAgB,kBAAkB,CAAC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,sBAAsB,EAAE,CAsE7F;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAiBF,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,CAkErE;AAED,wBAAgB,mBAAmB,IAAI,OAAO,CAO7C;AAED,wBAAgB,qBAAqB,IAAI;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAgBzD"}
|
package/dist/hermesSessionDb.js
CHANGED
|
@@ -2,6 +2,7 @@ import { readFileSync } from "node:fs";
|
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import Database from "better-sqlite3";
|
|
5
|
+
import { unwrapHermesStructuredContent } from "./hermesStructuredContent.js";
|
|
5
6
|
function hermesStateDbPath() {
|
|
6
7
|
const home = process.env.HERMES_HOME?.trim() || join(homedir(), ".hermes");
|
|
7
8
|
return join(home, "state.db");
|
|
@@ -24,6 +25,9 @@ function decodeMessageContent(raw) {
|
|
|
24
25
|
.map((part) => part.text)
|
|
25
26
|
.join("\n");
|
|
26
27
|
}
|
|
28
|
+
if (parsed && typeof parsed === "object") {
|
|
29
|
+
return unwrapHermesStructuredContent(raw);
|
|
30
|
+
}
|
|
27
31
|
}
|
|
28
32
|
catch {
|
|
29
33
|
// Plain text content.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keep in sync with @repo/backend-types/src/hermesStructuredContent.ts
|
|
3
|
+
* (duplicated here so the published bridge package stays self-contained).
|
|
4
|
+
*/
|
|
5
|
+
export declare function isHermesStructuredContent(content: string): boolean;
|
|
6
|
+
export declare function unwrapHermesStructuredContent(content: string): string;
|
|
7
|
+
export declare function looksLikeHermesStructuredStream(text: string): boolean;
|
|
8
|
+
//# sourceMappingURL=hermesStructuredContent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hermesStructuredContent.d.ts","sourceRoot":"","sources":["../src/hermesStructuredContent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0CH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAElE;AA6JD,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMrE;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIrE"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keep in sync with @repo/backend-types/src/hermesStructuredContent.ts
|
|
3
|
+
* (duplicated here so the published bridge package stays self-contained).
|
|
4
|
+
*/
|
|
5
|
+
function isRecord(value) {
|
|
6
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7
|
+
}
|
|
8
|
+
function asString(value) {
|
|
9
|
+
return typeof value === "string" ? value : undefined;
|
|
10
|
+
}
|
|
11
|
+
function stringArray(value) {
|
|
12
|
+
if (!Array.isArray(value))
|
|
13
|
+
return [];
|
|
14
|
+
return value.filter((entry) => typeof entry === "string");
|
|
15
|
+
}
|
|
16
|
+
function stringMatrix(value) {
|
|
17
|
+
if (!Array.isArray(value))
|
|
18
|
+
return [];
|
|
19
|
+
return value
|
|
20
|
+
.filter((row) => Array.isArray(row))
|
|
21
|
+
.map((row) => row.filter((cell) => typeof cell === "string"));
|
|
22
|
+
}
|
|
23
|
+
function parseHermesStructuredRoot(text) {
|
|
24
|
+
const trimmed = text.trim();
|
|
25
|
+
if (!trimmed.startsWith("{"))
|
|
26
|
+
return null;
|
|
27
|
+
let parsed;
|
|
28
|
+
try {
|
|
29
|
+
parsed = JSON.parse(trimmed);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
if (!isRecord(parsed) || typeof parsed.component !== "string") {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return parsed;
|
|
38
|
+
}
|
|
39
|
+
export function isHermesStructuredContent(content) {
|
|
40
|
+
return parseHermesStructuredRoot(content) !== null;
|
|
41
|
+
}
|
|
42
|
+
function hermesChildren(node) {
|
|
43
|
+
const children = node.children;
|
|
44
|
+
if (!Array.isArray(children))
|
|
45
|
+
return [];
|
|
46
|
+
return children.filter(isRecord);
|
|
47
|
+
}
|
|
48
|
+
function joinBlocks(blocks) {
|
|
49
|
+
return blocks
|
|
50
|
+
.map((block) => block.trim())
|
|
51
|
+
.filter((block) => block.length > 0)
|
|
52
|
+
.join("\n\n");
|
|
53
|
+
}
|
|
54
|
+
function markdownTable(headers, rows) {
|
|
55
|
+
if (headers.length === 0)
|
|
56
|
+
return "";
|
|
57
|
+
const separator = headers.map(() => "---");
|
|
58
|
+
const body = rows.map((row) => {
|
|
59
|
+
const cells = headers.map((_, index) => row[index] ?? "");
|
|
60
|
+
return `| ${cells.join(" | ")} |`;
|
|
61
|
+
});
|
|
62
|
+
return joinBlocks([
|
|
63
|
+
`| ${headers.join(" | ")} |`,
|
|
64
|
+
`| ${separator.join(" | ")} |`,
|
|
65
|
+
...body,
|
|
66
|
+
]);
|
|
67
|
+
}
|
|
68
|
+
function nodeToPlainText(node) {
|
|
69
|
+
const component = node.component;
|
|
70
|
+
if (typeof component !== "string")
|
|
71
|
+
return "";
|
|
72
|
+
switch (component) {
|
|
73
|
+
case "root":
|
|
74
|
+
return joinBlocks(hermesChildren(node).map(nodeToPlainText));
|
|
75
|
+
case "text":
|
|
76
|
+
return asString(node.text) ?? "";
|
|
77
|
+
case "heading": {
|
|
78
|
+
const text = asString(node.text);
|
|
79
|
+
if (!text)
|
|
80
|
+
return "";
|
|
81
|
+
const level = node.level === 3 ? 3 : 2;
|
|
82
|
+
return `${"#".repeat(level)} ${text}`;
|
|
83
|
+
}
|
|
84
|
+
case "table": {
|
|
85
|
+
const headers = stringArray(node.headers).length > 0
|
|
86
|
+
? stringArray(node.headers)
|
|
87
|
+
: stringArray(node.columns);
|
|
88
|
+
const rows = stringMatrix(node.rows);
|
|
89
|
+
if (headers.length === 0)
|
|
90
|
+
return "";
|
|
91
|
+
const caption = asString(node.caption);
|
|
92
|
+
const table = markdownTable(headers, rows);
|
|
93
|
+
return caption ? joinBlocks([caption, table]) : table;
|
|
94
|
+
}
|
|
95
|
+
case "list": {
|
|
96
|
+
const items = stringArray(node.items);
|
|
97
|
+
if (items.length === 0)
|
|
98
|
+
return "";
|
|
99
|
+
const style = node.style === "numbered" ? "numbered" : "bullet";
|
|
100
|
+
return items
|
|
101
|
+
.map((item, index) => (style === "numbered" ? `${index + 1}. ${item}` : `- ${item}`))
|
|
102
|
+
.join("\n");
|
|
103
|
+
}
|
|
104
|
+
case "code": {
|
|
105
|
+
const content = asString(node.content) ?? "";
|
|
106
|
+
const language = asString(node.language) ?? "";
|
|
107
|
+
return `\`\`\`${language}\n${content}\n\`\`\``;
|
|
108
|
+
}
|
|
109
|
+
case "link": {
|
|
110
|
+
const label = asString(node.label);
|
|
111
|
+
const url = asString(node.url);
|
|
112
|
+
if (label && url)
|
|
113
|
+
return `${label}: ${url}`;
|
|
114
|
+
return label ?? url ?? "";
|
|
115
|
+
}
|
|
116
|
+
case "key_value":
|
|
117
|
+
case "stat_cards": {
|
|
118
|
+
const items = Array.isArray(node.items) ? node.items.filter(isRecord) : [];
|
|
119
|
+
return joinBlocks(items.map((item) => {
|
|
120
|
+
const label = asString(item.label);
|
|
121
|
+
const value = asString(item.value);
|
|
122
|
+
if (!label || !value)
|
|
123
|
+
return "";
|
|
124
|
+
const hint = asString(item.hint);
|
|
125
|
+
return hint ? `${label}: ${value} (${hint})` : `${label}: ${value}`;
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
case "callout": {
|
|
129
|
+
const title = asString(node.title);
|
|
130
|
+
const body = asString(node.body) ?? "";
|
|
131
|
+
return joinBlocks([title, body].filter((part) => Boolean(part)));
|
|
132
|
+
}
|
|
133
|
+
case "choice": {
|
|
134
|
+
const prompt = asString(node.prompt) ?? "";
|
|
135
|
+
const options = Array.isArray(node.options) ? node.options.filter(isRecord) : [];
|
|
136
|
+
const optionLines = options
|
|
137
|
+
.map((option) => asString(option.label) ?? asString(option.id))
|
|
138
|
+
.filter((label) => Boolean(label))
|
|
139
|
+
.map((label) => `- ${label}`);
|
|
140
|
+
return joinBlocks([prompt, optionLines.join("\n")]);
|
|
141
|
+
}
|
|
142
|
+
case "yes_no":
|
|
143
|
+
return asString(node.prompt) ?? "";
|
|
144
|
+
case "suggestions": {
|
|
145
|
+
const items = Array.isArray(node.items) ? node.items.filter(isRecord) : [];
|
|
146
|
+
return items
|
|
147
|
+
.map((item) => asString(item.label) ?? asString(item.id))
|
|
148
|
+
.filter((label) => Boolean(label))
|
|
149
|
+
.map((label) => `- ${label}`)
|
|
150
|
+
.join("\n");
|
|
151
|
+
}
|
|
152
|
+
case "button_row": {
|
|
153
|
+
const buttons = Array.isArray(node.buttons) ? node.buttons.filter(isRecord) : [];
|
|
154
|
+
return buttons
|
|
155
|
+
.map((button) => asString(button.label) ?? asString(button.id))
|
|
156
|
+
.filter((label) => Boolean(label))
|
|
157
|
+
.join(" · ");
|
|
158
|
+
}
|
|
159
|
+
case "chart": {
|
|
160
|
+
const title = asString(node.title);
|
|
161
|
+
const labels = stringArray(node.labels);
|
|
162
|
+
const values = Array.isArray(node.values)
|
|
163
|
+
? node.values.map((value) => (typeof value === "number" ? String(value) : String(value ?? "")))
|
|
164
|
+
: [];
|
|
165
|
+
const series = labels
|
|
166
|
+
.map((label, index) => {
|
|
167
|
+
const value = values[index];
|
|
168
|
+
return value ? `${label}: ${value}` : label;
|
|
169
|
+
})
|
|
170
|
+
.join("\n");
|
|
171
|
+
return joinBlocks([title, series].filter((part) => Boolean(part)));
|
|
172
|
+
}
|
|
173
|
+
default: {
|
|
174
|
+
const text = asString(node.text) ?? asString(node.body) ?? asString(node.content);
|
|
175
|
+
if (text)
|
|
176
|
+
return text;
|
|
177
|
+
const children = hermesChildren(node);
|
|
178
|
+
if (children.length > 0) {
|
|
179
|
+
return joinBlocks(children.map(nodeToPlainText));
|
|
180
|
+
}
|
|
181
|
+
return "";
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
export function unwrapHermesStructuredContent(content) {
|
|
186
|
+
const root = parseHermesStructuredRoot(content);
|
|
187
|
+
if (!root)
|
|
188
|
+
return content;
|
|
189
|
+
const plain = nodeToPlainText(root).trim();
|
|
190
|
+
return plain.length > 0 ? plain : content;
|
|
191
|
+
}
|
|
192
|
+
export function looksLikeHermesStructuredStream(text) {
|
|
193
|
+
const trimmed = text.trimStart();
|
|
194
|
+
if (!trimmed.startsWith("{"))
|
|
195
|
+
return false;
|
|
196
|
+
return /^\{\s*"component"\s*:/.test(trimmed);
|
|
197
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hermesStructuredContent.test.d.ts","sourceRoot":"","sources":["../src/hermesStructuredContent.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import { isHermesStructuredContent, looksLikeHermesStructuredStream, unwrapHermesStructuredContent, } from "./hermesStructuredContent.js";
|
|
4
|
+
test("unwrapHermesStructuredContent extracts simple text block", () => {
|
|
5
|
+
const input = JSON.stringify({
|
|
6
|
+
component: "root",
|
|
7
|
+
children: [{ component: "text", text: "Det går fint! Hvordan står det til med deg?" }],
|
|
8
|
+
});
|
|
9
|
+
assert.equal(isHermesStructuredContent(input), true);
|
|
10
|
+
assert.equal(unwrapHermesStructuredContent(input), "Det går fint! Hvordan står det til med deg?");
|
|
11
|
+
});
|
|
12
|
+
test("looksLikeHermesStructuredStream detects early JSON envelope", () => {
|
|
13
|
+
assert.equal(looksLikeHermesStructuredStream('{"component":"root"'), true);
|
|
14
|
+
assert.equal(looksLikeHermesStructuredStream("Hello"), false);
|
|
15
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saleso.innovations/bridge",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.42",
|
|
4
4
|
"description": "Connect your Hermes agent to the Cleos iOS app via pairing code.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"lint": "eslint . --max-warnings 0",
|
|
37
37
|
"check-types": "tsc --noEmit",
|
|
38
38
|
"prepublishOnly": "npm run build",
|
|
39
|
-
"test": "node --import tsx --test src/hermesFiles.test.ts src/hermesSessionDb.test.ts src/renameHermesSession.test.ts src/shellSession.test.ts src/bridgeVersion.test.ts src/turnActivity.test.ts src/skillLearnedDetector.test.ts"
|
|
39
|
+
"test": "node --import tsx --test src/hermesFiles.test.ts src/hermesSessionDb.test.ts src/renameHermesSession.test.ts src/shellSession.test.ts src/bridgeVersion.test.ts src/turnActivity.test.ts src/skillLearnedDetector.test.ts src/hermesStructuredContent.test.ts"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"better-sqlite3": "^11.10.0",
|