modelstat 0.0.33 → 0.0.35
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/LICENSE +87 -0
- package/dist/cli.mjs +145 -6
- package/dist/cli.mjs.map +1 -1
- package/package.json +18 -19
- package/scripts/postinstall.mjs +63 -5
- package/vendor/tray-mac/build-app.sh +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
Copyright (c) 2026 ModelState Inc
|
|
2
|
+
|
|
3
|
+
Source-Available License
|
|
4
|
+
|
|
5
|
+
1. Grant of Rights
|
|
6
|
+
|
|
7
|
+
Subject to the terms of this License, you are granted a non-exclusive, worldwide,
|
|
8
|
+
non-transferable, non-sublicensable license to:
|
|
9
|
+
|
|
10
|
+
- View, read, and inspect the source code
|
|
11
|
+
- Build, modify, and run the software
|
|
12
|
+
- Use the software internally, including in production, solely to access or interact
|
|
13
|
+
with ModelState Inc’s hosted services
|
|
14
|
+
|
|
15
|
+
2. Permitted Use
|
|
16
|
+
|
|
17
|
+
You may use the software as a client, agent, or self-hosted component that connects
|
|
18
|
+
to and depends on ModelState Inc’s cloud or hosted services.
|
|
19
|
+
|
|
20
|
+
3. Restrictions
|
|
21
|
+
|
|
22
|
+
You may NOT, without explicit prior written permission from ModelState Inc:
|
|
23
|
+
|
|
24
|
+
- Use the software to provide a hosted, managed, or SaaS service to third parties
|
|
25
|
+
- Use the software in any product or service that competes with ModelState Inc
|
|
26
|
+
- Use the software to build or operate an alternative to ModelState Inc’s services
|
|
27
|
+
- Redistribute, sublicense, sell, license, or commercially exploit the software
|
|
28
|
+
- Offer the software (modified or unmodified) as part of a commercial offering
|
|
29
|
+
- Make the software available to third parties as a service
|
|
30
|
+
- Use the software for the benefit of third parties (including multi-tenant or shared environments)
|
|
31
|
+
- Circumvent or attempt to circumvent the limitations of this License
|
|
32
|
+
- Remove or alter any licensing, copyright, or attribution notices
|
|
33
|
+
|
|
34
|
+
4. Definition of Competing Service
|
|
35
|
+
|
|
36
|
+
“Competing Service” means any product or service that provides substantially similar
|
|
37
|
+
functionality to ModelState Inc’s offerings, including but not limited to:
|
|
38
|
+
|
|
39
|
+
- AI or LLM usage tracking, monitoring, or observability systems
|
|
40
|
+
- Model analytics platforms or dashboards
|
|
41
|
+
- Inference tracking, logging, or telemetry pipelines
|
|
42
|
+
- Evaluation, benchmarking, or quality analysis systems for AI/ML models
|
|
43
|
+
- Cost tracking, performance tracking, or optimization systems for model inference
|
|
44
|
+
- Any system that collects, processes, analyzes, or visualizes usage or behavior of AI or machine learning models, including large language models (LLMs), when offered as a product or service
|
|
45
|
+
|
|
46
|
+
5. Internal Use
|
|
47
|
+
|
|
48
|
+
Use of the software is permitted only for your internal business or personal use,
|
|
49
|
+
and not for the benefit of third parties.
|
|
50
|
+
|
|
51
|
+
6. Network Use Restriction
|
|
52
|
+
|
|
53
|
+
You may not use the software to expose APIs, endpoints, dashboards, or services to external
|
|
54
|
+
users except as part of accessing ModelState Inc’s services.
|
|
55
|
+
|
|
56
|
+
7. Data Extraction Restriction
|
|
57
|
+
|
|
58
|
+
You may not use the software to replicate, extract, reverse engineer, or reconstruct
|
|
59
|
+
ModelState Inc’s service behavior, APIs, data models, or system design for the purpose
|
|
60
|
+
of building, improving, or operating a competing system or service.
|
|
61
|
+
|
|
62
|
+
8. Ownership
|
|
63
|
+
|
|
64
|
+
All rights, title, and interest in the software remain exclusively with ModelState Inc.
|
|
65
|
+
The software is licensed, not sold.
|
|
66
|
+
|
|
67
|
+
9. Contributions
|
|
68
|
+
|
|
69
|
+
Unless explicitly agreed otherwise in writing, any contributions submitted to the software
|
|
70
|
+
grant ModelState Inc a perpetual, irrevocable, worldwide, royalty-free license to use,
|
|
71
|
+
modify, and distribute those contributions.
|
|
72
|
+
|
|
73
|
+
10. Termination
|
|
74
|
+
|
|
75
|
+
This License terminates automatically if you violate any of its terms.
|
|
76
|
+
Upon termination, you must immediately cease all use and delete all copies of the software.
|
|
77
|
+
|
|
78
|
+
11. Disclaimer of Warranty
|
|
79
|
+
|
|
80
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
81
|
+
EXPRESS OR IMPLIED.
|
|
82
|
+
|
|
83
|
+
12. Limitation of Liability
|
|
84
|
+
|
|
85
|
+
IN NO EVENT SHALL MODELSTATE INC BE LIABLE FOR ANY CLAIM, DAMAGES,
|
|
86
|
+
OR OTHER LIABILITY ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE
|
|
87
|
+
OR ITS USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/dist/cli.mjs
CHANGED
|
@@ -44268,6 +44268,88 @@ var init_prompts = __esm({
|
|
|
44268
44268
|
}
|
|
44269
44269
|
});
|
|
44270
44270
|
|
|
44271
|
+
// ../../packages/companion-core/src/pipeline/cognition.ts
|
|
44272
|
+
function buildCognitionUserPrompt(abstract) {
|
|
44273
|
+
return `Summary: "${abstract.replace(/\s+/g, " ").trim().slice(0, 480)}"
|
|
44274
|
+
|
|
44275
|
+
Output JSON only.`;
|
|
44276
|
+
}
|
|
44277
|
+
function parseCognitionReply(text) {
|
|
44278
|
+
const json = extractFirstJsonObject(text);
|
|
44279
|
+
if (!json) return null;
|
|
44280
|
+
let parsed;
|
|
44281
|
+
try {
|
|
44282
|
+
parsed = JSON.parse(json);
|
|
44283
|
+
} catch {
|
|
44284
|
+
return null;
|
|
44285
|
+
}
|
|
44286
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
44287
|
+
const obj = parsed;
|
|
44288
|
+
return {
|
|
44289
|
+
emotions: sanitiseTags(obj.emotions),
|
|
44290
|
+
meta: sanitiseTags(obj.meta)
|
|
44291
|
+
};
|
|
44292
|
+
}
|
|
44293
|
+
function sanitiseTags(raw) {
|
|
44294
|
+
if (!Array.isArray(raw)) return [];
|
|
44295
|
+
const seen = /* @__PURE__ */ new Set();
|
|
44296
|
+
const out = [];
|
|
44297
|
+
for (const t of raw) {
|
|
44298
|
+
if (typeof t !== "string") continue;
|
|
44299
|
+
const cleaned = t.toLowerCase().normalize("NFKD").replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").replace(/^-+|-+$/g, "").slice(0, MAX_COGNITION_TAG_CHARS);
|
|
44300
|
+
if (!cleaned) continue;
|
|
44301
|
+
if (seen.has(cleaned)) continue;
|
|
44302
|
+
seen.add(cleaned);
|
|
44303
|
+
out.push(cleaned);
|
|
44304
|
+
if (out.length >= MAX_COGNITION_TAGS_PER_FIELD) break;
|
|
44305
|
+
}
|
|
44306
|
+
return out;
|
|
44307
|
+
}
|
|
44308
|
+
function formatCognitionSuffix(c) {
|
|
44309
|
+
if (!c) return "";
|
|
44310
|
+
const parts = [];
|
|
44311
|
+
if (c.emotions.length > 0) parts.push(`[Mood: ${c.emotions.join(", ")}]`);
|
|
44312
|
+
if (c.meta.length > 0) parts.push(`[Mind: ${c.meta.join(", ")}]`);
|
|
44313
|
+
return parts.join(" ");
|
|
44314
|
+
}
|
|
44315
|
+
function extractFirstJsonObject(s) {
|
|
44316
|
+
const start = s.indexOf("{");
|
|
44317
|
+
if (start < 0) return null;
|
|
44318
|
+
let depth = 0;
|
|
44319
|
+
let inStr = false;
|
|
44320
|
+
let escape2 = false;
|
|
44321
|
+
for (let i = start; i < s.length; i++) {
|
|
44322
|
+
const ch = s[i];
|
|
44323
|
+
if (inStr) {
|
|
44324
|
+
if (escape2) escape2 = false;
|
|
44325
|
+
else if (ch === "\\") escape2 = true;
|
|
44326
|
+
else if (ch === '"') inStr = false;
|
|
44327
|
+
continue;
|
|
44328
|
+
}
|
|
44329
|
+
if (ch === '"') {
|
|
44330
|
+
inStr = true;
|
|
44331
|
+
continue;
|
|
44332
|
+
}
|
|
44333
|
+
if (ch === "{") depth++;
|
|
44334
|
+
else if (ch === "}") {
|
|
44335
|
+
depth--;
|
|
44336
|
+
if (depth === 0) return s.slice(start, i + 1);
|
|
44337
|
+
}
|
|
44338
|
+
}
|
|
44339
|
+
return null;
|
|
44340
|
+
}
|
|
44341
|
+
var COGNITION_SYSTEM_PROMPT, MAX_COGNITION_TAGS_PER_FIELD, MAX_COGNITION_TAG_CHARS, COGNITION_MAX_TOKENS, COGNITION_TEMPERATURE;
|
|
44342
|
+
var init_cognition = __esm({
|
|
44343
|
+
"../../packages/companion-core/src/pipeline/cognition.ts"() {
|
|
44344
|
+
"use strict";
|
|
44345
|
+
COGNITION_SYSTEM_PROMPT = 'You read a one-sentence summary of an AI-coding work session and identify the user\'s emotional state and meta-cognitive state. Output JSON only \u2014 first character of reply is `{`. Schema: {"emotions":[],"meta":[]}. emotions: \u2264 3 short lowercase mood tags such as frustrated, curious, excited, focused, calm, confused, anxious, satisfied, proud, bored, energised. meta: \u2264 3 short lowercase tags about cognitive mode, such as debugging, exploring, planning, designing, learning, deciding, reviewing, refactoring, investigating, documenting. Each tag \u2264 24 chars, single word or hyphenated, no punctuation. Only emit a tag if the summary gives clear evidence \u2014 return [] for either field when unsure. Do not invent emotions the user did not display. No prose, no markdown.';
|
|
44346
|
+
MAX_COGNITION_TAGS_PER_FIELD = 3;
|
|
44347
|
+
MAX_COGNITION_TAG_CHARS = 24;
|
|
44348
|
+
COGNITION_MAX_TOKENS = 80;
|
|
44349
|
+
COGNITION_TEMPERATURE = 0.2;
|
|
44350
|
+
}
|
|
44351
|
+
});
|
|
44352
|
+
|
|
44271
44353
|
// ../../packages/companion-core/src/pipeline/index.ts
|
|
44272
44354
|
async function buildSegmentsForSession(events, adapters2) {
|
|
44273
44355
|
if (events.length === 0) return [];
|
|
@@ -44428,6 +44510,15 @@ Write the SHORTEST keyword-dense paragraph (1-3 sentences, \u2264${ABSTRACT_OUTP
|
|
|
44428
44510
|
}
|
|
44429
44511
|
}
|
|
44430
44512
|
const redacted = { text: abstractText, counts };
|
|
44513
|
+
let abstractWithCognition = redacted.text;
|
|
44514
|
+
if (adapters2.cognize) {
|
|
44515
|
+
try {
|
|
44516
|
+
const tags2 = await adapters2.cognize({ abstract: redacted.text });
|
|
44517
|
+
const suffix = formatCognitionSuffix(tags2);
|
|
44518
|
+
if (suffix) abstractWithCognition = `${redacted.text} ${suffix}`;
|
|
44519
|
+
} catch {
|
|
44520
|
+
}
|
|
44521
|
+
}
|
|
44431
44522
|
const tags = [
|
|
44432
44523
|
{ root_key: "tools", name: first.tool, confidence: 1 },
|
|
44433
44524
|
{ root_key: "providers", name: first.provider, confidence: 1 }
|
|
@@ -44469,7 +44560,7 @@ Write the SHORTEST keyword-dense paragraph (1-3 sentences, \u2264${ABSTRACT_OUTP
|
|
|
44469
44560
|
// 400) — well below the 512 storage cap. Models occasionally
|
|
44470
44561
|
// overshoot the prompt's "≤N chars" instruction; the slice is the
|
|
44471
44562
|
// hard guarantee the dashboard relies on.
|
|
44472
|
-
abstract:
|
|
44563
|
+
abstract: abstractWithCognition.slice(0, ABSTRACT_OUTPUT_MAX_CHARS),
|
|
44473
44564
|
tokens,
|
|
44474
44565
|
tags,
|
|
44475
44566
|
// counts is `Record<string, number>` after the optional model
|
|
@@ -44540,8 +44631,10 @@ var init_pipeline = __esm({
|
|
|
44540
44631
|
init_redact();
|
|
44541
44632
|
init_ids();
|
|
44542
44633
|
init_prompts();
|
|
44634
|
+
init_cognition();
|
|
44543
44635
|
init_redact();
|
|
44544
44636
|
init_prompts();
|
|
44637
|
+
init_cognition();
|
|
44545
44638
|
SEGMENT_TIME_GAP_MS = 15 * 6e4;
|
|
44546
44639
|
SEGMENT_TOPIC_THRESHOLD = 0.35;
|
|
44547
44640
|
SEGMENT_MAX_TURNS = 100;
|
|
@@ -44743,10 +44836,46 @@ function ollamaSummarize(cfg = defaultOllamaConfig()) {
|
|
|
44743
44836
|
return (body.message?.content ?? "").trim().slice(0, 240);
|
|
44744
44837
|
};
|
|
44745
44838
|
}
|
|
44839
|
+
function ollamaCognize(cfg = defaultOllamaConfig()) {
|
|
44840
|
+
return async ({ abstract }) => {
|
|
44841
|
+
if (!abstract || abstract.trim().length < 12) return null;
|
|
44842
|
+
let res;
|
|
44843
|
+
try {
|
|
44844
|
+
res = await fetch(`${cfg.baseUrl.replace(/\/+$/, "")}/api/chat`, {
|
|
44845
|
+
method: "POST",
|
|
44846
|
+
headers: { "content-type": "application/json" },
|
|
44847
|
+
body: JSON.stringify({
|
|
44848
|
+
model: cfg.chatModel,
|
|
44849
|
+
stream: false,
|
|
44850
|
+
format: "json",
|
|
44851
|
+
options: {
|
|
44852
|
+
temperature: COGNITION_TEMPERATURE,
|
|
44853
|
+
num_predict: COGNITION_MAX_TOKENS
|
|
44854
|
+
},
|
|
44855
|
+
messages: [
|
|
44856
|
+
{ role: "system", content: COGNITION_SYSTEM_PROMPT },
|
|
44857
|
+
{ role: "user", content: buildCognitionUserPrompt(abstract) }
|
|
44858
|
+
]
|
|
44859
|
+
})
|
|
44860
|
+
});
|
|
44861
|
+
} catch {
|
|
44862
|
+
return null;
|
|
44863
|
+
}
|
|
44864
|
+
if (!res.ok) return null;
|
|
44865
|
+
let body;
|
|
44866
|
+
try {
|
|
44867
|
+
body = await res.json();
|
|
44868
|
+
} catch {
|
|
44869
|
+
return null;
|
|
44870
|
+
}
|
|
44871
|
+
return parseCognitionReply(body.message?.content ?? "");
|
|
44872
|
+
};
|
|
44873
|
+
}
|
|
44746
44874
|
var init_ollama = __esm({
|
|
44747
44875
|
"../../packages/companion-core/src/node/ollama.ts"() {
|
|
44748
44876
|
"use strict";
|
|
44749
44877
|
init_prompts();
|
|
44878
|
+
init_cognition();
|
|
44750
44879
|
}
|
|
44751
44880
|
});
|
|
44752
44881
|
|
|
@@ -44916,6 +45045,7 @@ __export(node_exports, {
|
|
|
44916
45045
|
defaultOllamaConfig: () => defaultOllamaConfig,
|
|
44917
45046
|
ensureLlamaModel: () => ensureLlamaModel,
|
|
44918
45047
|
llamaSummarize: () => llamaSummarize,
|
|
45048
|
+
ollamaCognize: () => ollamaCognize,
|
|
44919
45049
|
ollamaEmbed: () => ollamaEmbed,
|
|
44920
45050
|
ollamaSummarize: () => ollamaSummarize,
|
|
44921
45051
|
ollamaTokenize: () => ollamaTokenize
|
|
@@ -44969,7 +45099,16 @@ async function getAdapters() {
|
|
|
44969
45099
|
adapters = {
|
|
44970
45100
|
embed: ollamaEmbed(ollamaCfg),
|
|
44971
45101
|
summarize: ollamaSummarize(ollamaCfg),
|
|
44972
|
-
tokenize: ollamaTokenize()
|
|
45102
|
+
tokenize: ollamaTokenize(),
|
|
45103
|
+
// Cognition pass — best-effort. Reads each abstract back out
|
|
45104
|
+
// and tags the user's mood + meta-cognitive mode, appending a
|
|
45105
|
+
// "[Mood: …] [Mind: …]" suffix the server proposer reads as
|
|
45106
|
+
// ordinary abstract text. Free, runs locally on the same Ollama
|
|
45107
|
+
// daemon as the summariser. The bundled (node-llama-cpp) path
|
|
45108
|
+
// doesn't get cognition — it'd require a second model context
|
|
45109
|
+
// and the segment ships fine without the suffix; install Ollama
|
|
45110
|
+
// for emotion tagging.
|
|
45111
|
+
cognize: ollamaCognize(ollamaCfg)
|
|
44973
45112
|
};
|
|
44974
45113
|
return adapters;
|
|
44975
45114
|
}
|
|
@@ -45129,7 +45268,7 @@ var init_scan = __esm({
|
|
|
45129
45268
|
init_pipeline2();
|
|
45130
45269
|
init_config2();
|
|
45131
45270
|
init_api();
|
|
45132
|
-
AGENT_VERSION = "agent-0.0.
|
|
45271
|
+
AGENT_VERSION = "agent-0.0.35";
|
|
45133
45272
|
BATCH_MAX_EVENTS = 2e3;
|
|
45134
45273
|
}
|
|
45135
45274
|
});
|
|
@@ -45272,7 +45411,7 @@ var PROCESSING_VERSION;
|
|
|
45272
45411
|
var init_processing_version = __esm({
|
|
45273
45412
|
"src/processing-version.ts"() {
|
|
45274
45413
|
"use strict";
|
|
45275
|
-
PROCESSING_VERSION =
|
|
45414
|
+
PROCESSING_VERSION = 3;
|
|
45276
45415
|
}
|
|
45277
45416
|
});
|
|
45278
45417
|
|
|
@@ -47221,7 +47360,7 @@ var init_daemon = __esm({
|
|
|
47221
47360
|
init_config2();
|
|
47222
47361
|
init_lock();
|
|
47223
47362
|
init_scan();
|
|
47224
|
-
AGENT_VERSION2 = "agent-0.0.
|
|
47363
|
+
AGENT_VERSION2 = "agent-0.0.35";
|
|
47225
47364
|
HEARTBEAT_INTERVAL_MS = 1e4;
|
|
47226
47365
|
SCAN_INTERVAL_MS = 5 * 60 * 1e3;
|
|
47227
47366
|
status = {
|
|
@@ -47646,7 +47785,7 @@ function tryOpenBrowser(url) {
|
|
|
47646
47785
|
return false;
|
|
47647
47786
|
}
|
|
47648
47787
|
}
|
|
47649
|
-
var AGENT_VERSION3 = "agent-0.0.
|
|
47788
|
+
var AGENT_VERSION3 = "agent-0.0.35";
|
|
47650
47789
|
function osFamily() {
|
|
47651
47790
|
const p = platform4();
|
|
47652
47791
|
if (p === "darwin") return "macos";
|