@pellux/goodvibes-agent 1.6.2 → 1.6.3
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/CHANGELOG.md +4 -0
- package/README.md +1 -1
- package/dist/package/main.js +648 -94
- package/package.json +2 -2
- package/src/tools/agent-harness-background-processes.ts +3 -2
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Product-facing release notes for GoodVibes Agent.
|
|
4
4
|
|
|
5
|
+
## 1.6.3 - 2026-07-07
|
|
6
|
+
|
|
7
|
+
- SDK 1.4.0 pin: the shared daemon contracts gain server-side companion-chat turn control — a true stop verb (provider stream aborted, honest partial persisted), queue-when-busy sends, and steer (interrupt-and-send-now). No agent-side behavior changes; agent session turns already had lifecycle control on the operator wire.
|
|
8
|
+
|
|
5
9
|
## 1.6.2 - 2026-07-07
|
|
6
10
|
|
|
7
11
|
- Updated to SDK 1.3.3: the macOS capability-limit classification now matches Apple SQLite's exact refusal message, so compiled binaries report the honest limit instead of an error.
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# GoodVibes Agent
|
|
2
2
|
|
|
3
3
|
[](https://opensource.org/licenses/MIT)
|
|
4
|
-
[](#install)
|
|
5
5
|
|
|
6
6
|
GoodVibes Agent is the installable autonomous operator assistant for GoodVibes. It keeps the existing terminal renderer and workspace bones, but the product goal is different from a vibecoding harness: the user should experience one assistant that can chat, plan, remember, research, schedule, send, generate, run visible agents, and operate the GoodVibes daemon contract with clear confirmation gates.
|
|
7
7
|
|
package/dist/package/main.js
CHANGED
|
@@ -4463,7 +4463,7 @@ var init_mcp = __esm(() => {
|
|
|
4463
4463
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/version.js
|
|
4464
4464
|
import { readFileSync as readFileSync3 } from "fs";
|
|
4465
4465
|
import { join as join4 } from "path";
|
|
4466
|
-
var version = "1.
|
|
4466
|
+
var version = "1.4.0", VERSION2;
|
|
4467
4467
|
var init_version = __esm(() => {
|
|
4468
4468
|
try {
|
|
4469
4469
|
const pkg = JSON.parse(readFileSync3(join4(import.meta.dir, "..", "..", "package.json"), "utf-8"));
|
|
@@ -264004,8 +264004,8 @@ var FOUNDATION_METADATA;
|
|
|
264004
264004
|
var init_foundation_metadata = __esm(() => {
|
|
264005
264005
|
FOUNDATION_METADATA = {
|
|
264006
264006
|
productId: "goodvibes",
|
|
264007
|
-
productVersion: "1.
|
|
264008
|
-
operatorMethodCount:
|
|
264007
|
+
productVersion: "1.4.0",
|
|
264008
|
+
operatorMethodCount: 329,
|
|
264009
264009
|
operatorEventCount: 31,
|
|
264010
264010
|
peerEndpointCount: 6
|
|
264011
264011
|
};
|
|
@@ -264019,7 +264019,7 @@ var init_operator_contract = __esm(() => {
|
|
|
264019
264019
|
product: {
|
|
264020
264020
|
id: "goodvibes",
|
|
264021
264021
|
surface: "operator",
|
|
264022
|
-
version: "1.
|
|
264022
|
+
version: "1.4.0"
|
|
264023
264023
|
},
|
|
264024
264024
|
auth: {
|
|
264025
264025
|
modes: [
|
|
@@ -286083,6 +286083,16 @@ var init_operator_contract = __esm(() => {
|
|
|
286083
286083
|
},
|
|
286084
286084
|
createdAt: {
|
|
286085
286085
|
type: "number"
|
|
286086
|
+
},
|
|
286087
|
+
deliveryState: {
|
|
286088
|
+
type: "string",
|
|
286089
|
+
enum: [
|
|
286090
|
+
"cancelled",
|
|
286091
|
+
"queued"
|
|
286092
|
+
]
|
|
286093
|
+
},
|
|
286094
|
+
inReplyTo: {
|
|
286095
|
+
type: "string"
|
|
286086
286096
|
}
|
|
286087
286097
|
},
|
|
286088
286098
|
required: [
|
|
@@ -286161,6 +286171,99 @@ var init_operator_contract = __esm(() => {
|
|
|
286161
286171
|
},
|
|
286162
286172
|
invokable: true
|
|
286163
286173
|
},
|
|
286174
|
+
{
|
|
286175
|
+
id: "companion.chat.messages.steer",
|
|
286176
|
+
title: "Steer Companion Chat (Interrupt And Send)",
|
|
286177
|
+
description: 'Send a message that runs IMMEDIATELY, interrupting the in-flight turn if one is running. The message jumps to the front of the pending-turn queue; the active turn is cancelled through the same finalization path as companion.chat.turns.cancel (any non-empty partial reply is persisted with `deliveryState: "cancelled"` and the terminal `turn.cancelled` event reaches every subscriber), then the steered message\'s turn starts. Messages queued behind an active turn keep their places behind the steer. With no turn running this behaves as an ordinary send. Accepts the same payload as companion.chat.messages.create (`body`/`content`, `attachments`, `metadata`). Returns the new message id, `steered: true`, and `cancelledTurnId` when a turn was interrupted. Ordinary sends posted while a turn is running are QUEUED (transcript-visible immediately with `deliveryState: "queued"`, answered in order) \u2014 steer is the explicit jump-the-line verb.',
|
|
286178
|
+
category: "companion",
|
|
286179
|
+
source: "builtin",
|
|
286180
|
+
access: "authenticated",
|
|
286181
|
+
transport: [
|
|
286182
|
+
"http",
|
|
286183
|
+
"ws"
|
|
286184
|
+
],
|
|
286185
|
+
scopes: [
|
|
286186
|
+
"write:sessions"
|
|
286187
|
+
],
|
|
286188
|
+
http: {
|
|
286189
|
+
method: "POST",
|
|
286190
|
+
path: "/api/companion/chat/sessions/{sessionId}/messages/steer"
|
|
286191
|
+
},
|
|
286192
|
+
inputSchema: {
|
|
286193
|
+
type: "object",
|
|
286194
|
+
properties: {
|
|
286195
|
+
sessionId: {
|
|
286196
|
+
type: "string"
|
|
286197
|
+
},
|
|
286198
|
+
body: {
|
|
286199
|
+
type: "string"
|
|
286200
|
+
},
|
|
286201
|
+
content: {
|
|
286202
|
+
type: "string"
|
|
286203
|
+
},
|
|
286204
|
+
attachments: {
|
|
286205
|
+
type: "array",
|
|
286206
|
+
items: {
|
|
286207
|
+
type: "object",
|
|
286208
|
+
properties: {
|
|
286209
|
+
artifactId: {
|
|
286210
|
+
type: "string"
|
|
286211
|
+
},
|
|
286212
|
+
label: {
|
|
286213
|
+
type: "string"
|
|
286214
|
+
},
|
|
286215
|
+
metadata: {
|
|
286216
|
+
type: "object",
|
|
286217
|
+
properties: {},
|
|
286218
|
+
additionalProperties: false
|
|
286219
|
+
}
|
|
286220
|
+
},
|
|
286221
|
+
required: [
|
|
286222
|
+
"artifactId"
|
|
286223
|
+
],
|
|
286224
|
+
additionalProperties: false
|
|
286225
|
+
}
|
|
286226
|
+
},
|
|
286227
|
+
metadata: {
|
|
286228
|
+
type: "object",
|
|
286229
|
+
properties: {},
|
|
286230
|
+
additionalProperties: false
|
|
286231
|
+
}
|
|
286232
|
+
},
|
|
286233
|
+
required: [
|
|
286234
|
+
"sessionId"
|
|
286235
|
+
],
|
|
286236
|
+
additionalProperties: true
|
|
286237
|
+
},
|
|
286238
|
+
outputSchema: {
|
|
286239
|
+
type: "object",
|
|
286240
|
+
properties: {
|
|
286241
|
+
sessionId: {
|
|
286242
|
+
type: "string"
|
|
286243
|
+
},
|
|
286244
|
+
messageId: {
|
|
286245
|
+
type: "string"
|
|
286246
|
+
},
|
|
286247
|
+
steered: {
|
|
286248
|
+
type: "boolean"
|
|
286249
|
+
},
|
|
286250
|
+
cancelledTurnId: {
|
|
286251
|
+
type: "string"
|
|
286252
|
+
},
|
|
286253
|
+
turnStarted: {
|
|
286254
|
+
type: "boolean"
|
|
286255
|
+
}
|
|
286256
|
+
},
|
|
286257
|
+
required: [
|
|
286258
|
+
"sessionId",
|
|
286259
|
+
"messageId",
|
|
286260
|
+
"steered",
|
|
286261
|
+
"turnStarted"
|
|
286262
|
+
],
|
|
286263
|
+
additionalProperties: false
|
|
286264
|
+
},
|
|
286265
|
+
invokable: true
|
|
286266
|
+
},
|
|
286164
286267
|
{
|
|
286165
286268
|
id: "companion.chat.sessions.close",
|
|
286166
286269
|
title: "Close Companion Chat Session",
|
|
@@ -286627,6 +286730,16 @@ var init_operator_contract = __esm(() => {
|
|
|
286627
286730
|
},
|
|
286628
286731
|
createdAt: {
|
|
286629
286732
|
type: "number"
|
|
286733
|
+
},
|
|
286734
|
+
deliveryState: {
|
|
286735
|
+
type: "string",
|
|
286736
|
+
enum: [
|
|
286737
|
+
"cancelled",
|
|
286738
|
+
"queued"
|
|
286739
|
+
]
|
|
286740
|
+
},
|
|
286741
|
+
inReplyTo: {
|
|
286742
|
+
type: "string"
|
|
286630
286743
|
}
|
|
286631
286744
|
},
|
|
286632
286745
|
required: [
|
|
@@ -286935,6 +287048,68 @@ var init_operator_contract = __esm(() => {
|
|
|
286935
287048
|
},
|
|
286936
287049
|
invokable: true
|
|
286937
287050
|
},
|
|
287051
|
+
{
|
|
287052
|
+
id: "companion.chat.turns.cancel",
|
|
287053
|
+
title: "Cancel Companion Chat Turn",
|
|
287054
|
+
description: 'Stop the in-flight turn for a companion chat session \u2014 a true server-side stop: the provider stream is aborted, any non-empty partial reply is persisted to the transcript with an explicit `deliveryState: "cancelled"` marker (an honest partial, never disguised as a complete reply) AND committed to the model-facing conversation history with an explicit interruption note \u2014 later turns can reason about what the user saw and stopped, which is usually what a follow-up or steer refers to, and the terminal `turn.cancelled` event is published to every subscriber of the session stream so a stop from one client converges on all others. Any announced tool call without a result is closed with a synthetic error `turn.tool_result` before the terminal event. Optional `turnId` guards against cancelling a newer turn a stale stop raced against (409 TURN_MISMATCH). No turn in flight is the benign 404 NO_ACTIVE_TURN (the turn finished before the stop landed). Repeat cancels are idempotent successes. The session stays open; the next message starts a fresh turn normally.',
|
|
287055
|
+
category: "companion",
|
|
287056
|
+
source: "builtin",
|
|
287057
|
+
access: "authenticated",
|
|
287058
|
+
transport: [
|
|
287059
|
+
"http",
|
|
287060
|
+
"ws"
|
|
287061
|
+
],
|
|
287062
|
+
scopes: [
|
|
287063
|
+
"write:sessions"
|
|
287064
|
+
],
|
|
287065
|
+
http: {
|
|
287066
|
+
method: "POST",
|
|
287067
|
+
path: "/api/companion/chat/sessions/{sessionId}/turns/cancel"
|
|
287068
|
+
},
|
|
287069
|
+
inputSchema: {
|
|
287070
|
+
type: "object",
|
|
287071
|
+
properties: {
|
|
287072
|
+
sessionId: {
|
|
287073
|
+
type: "string"
|
|
287074
|
+
},
|
|
287075
|
+
turnId: {
|
|
287076
|
+
type: "string"
|
|
287077
|
+
}
|
|
287078
|
+
},
|
|
287079
|
+
required: [
|
|
287080
|
+
"sessionId"
|
|
287081
|
+
],
|
|
287082
|
+
additionalProperties: true
|
|
287083
|
+
},
|
|
287084
|
+
outputSchema: {
|
|
287085
|
+
type: "object",
|
|
287086
|
+
properties: {
|
|
287087
|
+
sessionId: {
|
|
287088
|
+
type: "string"
|
|
287089
|
+
},
|
|
287090
|
+
turnId: {
|
|
287091
|
+
type: "string"
|
|
287092
|
+
},
|
|
287093
|
+
cancelled: {
|
|
287094
|
+
type: "boolean"
|
|
287095
|
+
},
|
|
287096
|
+
alreadyCancelled: {
|
|
287097
|
+
type: "boolean"
|
|
287098
|
+
},
|
|
287099
|
+
partialPersisted: {
|
|
287100
|
+
type: "boolean"
|
|
287101
|
+
}
|
|
287102
|
+
},
|
|
287103
|
+
required: [
|
|
287104
|
+
"sessionId",
|
|
287105
|
+
"turnId",
|
|
287106
|
+
"cancelled",
|
|
287107
|
+
"partialPersisted"
|
|
287108
|
+
],
|
|
287109
|
+
additionalProperties: false
|
|
287110
|
+
},
|
|
287111
|
+
invokable: true
|
|
287112
|
+
},
|
|
286938
287113
|
{
|
|
286939
287114
|
id: "config.get",
|
|
286940
287115
|
title: "Get Config",
|
|
@@ -345393,10 +345568,10 @@ var init_operator_contract = __esm(() => {
|
|
|
345393
345568
|
}
|
|
345394
345569
|
],
|
|
345395
345570
|
schemaCoverage: {
|
|
345396
|
-
methods:
|
|
345397
|
-
typedInputs:
|
|
345571
|
+
methods: 329,
|
|
345572
|
+
typedInputs: 329,
|
|
345398
345573
|
genericInputs: 0,
|
|
345399
|
-
typedOutputs:
|
|
345574
|
+
typedOutputs: 329,
|
|
345400
345575
|
genericOutputs: 0
|
|
345401
345576
|
},
|
|
345402
345577
|
eventCoverage: {
|
|
@@ -345405,8 +345580,8 @@ var init_operator_contract = __esm(() => {
|
|
|
345405
345580
|
withWireEvents: 31
|
|
345406
345581
|
},
|
|
345407
345582
|
validationCoverage: {
|
|
345408
|
-
methods:
|
|
345409
|
-
validated:
|
|
345583
|
+
methods: 329,
|
|
345584
|
+
validated: 327,
|
|
345410
345585
|
skippedGeneric: 0,
|
|
345411
345586
|
skippedUntyped: 2
|
|
345412
345587
|
}
|
|
@@ -345502,12 +345677,14 @@ var init_operator_method_ids = __esm(() => {
|
|
|
345502
345677
|
"companion.chat.messages.edit",
|
|
345503
345678
|
"companion.chat.messages.list",
|
|
345504
345679
|
"companion.chat.messages.retry",
|
|
345680
|
+
"companion.chat.messages.steer",
|
|
345505
345681
|
"companion.chat.sessions.close",
|
|
345506
345682
|
"companion.chat.sessions.create",
|
|
345507
345683
|
"companion.chat.sessions.delete",
|
|
345508
345684
|
"companion.chat.sessions.get",
|
|
345509
345685
|
"companion.chat.sessions.list",
|
|
345510
345686
|
"companion.chat.sessions.update",
|
|
345687
|
+
"companion.chat.turns.cancel",
|
|
345511
345688
|
"config.get",
|
|
345512
345689
|
"config.set",
|
|
345513
345690
|
"continuity.snapshot",
|
|
@@ -450511,7 +450688,9 @@ var init_operator_contract_schemas_runtime = __esm(() => {
|
|
|
450511
450688
|
role: COMPANION_CHAT_MESSAGE_ROLE_SCHEMA,
|
|
450512
450689
|
content: STRING_SCHEMA,
|
|
450513
450690
|
attachments: arraySchema(COMPANION_CHAT_ATTACHMENT_SCHEMA),
|
|
450514
|
-
createdAt: NUMBER_SCHEMA
|
|
450691
|
+
createdAt: NUMBER_SCHEMA,
|
|
450692
|
+
deliveryState: enumSchema(["cancelled", "queued"]),
|
|
450693
|
+
inReplyTo: STRING_SCHEMA
|
|
450515
450694
|
}, ["id", "sessionId", "role", "content", "attachments", "createdAt"]);
|
|
450516
450695
|
COMPANION_CHAT_SESSION_WITH_MESSAGES_SCHEMA = objectSchema({
|
|
450517
450696
|
session: COMPANION_CHAT_SESSION_SCHEMA,
|
|
@@ -453393,6 +453572,51 @@ var init_method_catalog_control_companion = __esm(() => {
|
|
|
453393
453572
|
turnStarted: BOOLEAN_SCHEMA
|
|
453394
453573
|
}, ["sessionId", "editedFrom", "messageId", "supersededMessageIds", "turnStarted"])
|
|
453395
453574
|
}),
|
|
453575
|
+
methodDescriptor({
|
|
453576
|
+
id: "companion.chat.messages.steer",
|
|
453577
|
+
title: "Steer Companion Chat (Interrupt And Send)",
|
|
453578
|
+
description: 'Send a message that runs IMMEDIATELY, interrupting the in-flight turn if one is running. The message jumps to the front of the pending-turn queue; the active turn is cancelled through the same finalization path as companion.chat.turns.cancel (any non-empty partial reply is persisted with `deliveryState: "cancelled"` and the terminal `turn.cancelled` event reaches every subscriber), then the steered message\'s turn starts. Messages queued behind an active turn keep their places behind the steer. With no turn running this behaves as an ordinary send. Accepts the same payload as companion.chat.messages.create (`body`/`content`, `attachments`, `metadata`). Returns the new message id, `steered: true`, and `cancelledTurnId` when a turn was interrupted. Ordinary sends posted while a turn is running are QUEUED (transcript-visible immediately with `deliveryState: "queued"`, answered in order) \u2014 steer is the explicit jump-the-line verb.',
|
|
453579
|
+
category: "companion",
|
|
453580
|
+
scopes: ["write:sessions"],
|
|
453581
|
+
http: { method: "POST", path: "/api/companion/chat/sessions/{sessionId}/messages/steer" },
|
|
453582
|
+
inputSchema: bodyEnvelopeSchema({
|
|
453583
|
+
sessionId: STRING_SCHEMA,
|
|
453584
|
+
body: STRING_SCHEMA,
|
|
453585
|
+
content: STRING_SCHEMA,
|
|
453586
|
+
attachments: arraySchema(objectSchema({
|
|
453587
|
+
artifactId: STRING_SCHEMA,
|
|
453588
|
+
label: STRING_SCHEMA,
|
|
453589
|
+
metadata: objectSchema({}, [])
|
|
453590
|
+
}, ["artifactId"])),
|
|
453591
|
+
metadata: objectSchema({}, [])
|
|
453592
|
+
}, ["sessionId"]),
|
|
453593
|
+
outputSchema: objectSchema({
|
|
453594
|
+
sessionId: STRING_SCHEMA,
|
|
453595
|
+
messageId: STRING_SCHEMA,
|
|
453596
|
+
steered: BOOLEAN_SCHEMA,
|
|
453597
|
+
cancelledTurnId: STRING_SCHEMA,
|
|
453598
|
+
turnStarted: BOOLEAN_SCHEMA
|
|
453599
|
+
}, ["sessionId", "messageId", "steered", "turnStarted"])
|
|
453600
|
+
}),
|
|
453601
|
+
methodDescriptor({
|
|
453602
|
+
id: "companion.chat.turns.cancel",
|
|
453603
|
+
title: "Cancel Companion Chat Turn",
|
|
453604
|
+
description: 'Stop the in-flight turn for a companion chat session \u2014 a true server-side stop: the provider stream is aborted, any non-empty partial reply is persisted to the transcript with an explicit `deliveryState: "cancelled"` marker (an honest partial, never disguised as a complete reply) AND committed to the model-facing conversation history with an explicit interruption note \u2014 later turns can reason about what the user saw and stopped, which is usually what a follow-up or steer refers to, and the terminal `turn.cancelled` event is published to every subscriber of the session stream so a stop from one client converges on all others. Any announced tool call without a result is closed with a synthetic error `turn.tool_result` before the terminal event. Optional `turnId` guards against cancelling a newer turn a stale stop raced against (409 TURN_MISMATCH). No turn in flight is the benign 404 NO_ACTIVE_TURN (the turn finished before the stop landed). Repeat cancels are idempotent successes. The session stays open; the next message starts a fresh turn normally.',
|
|
453605
|
+
category: "companion",
|
|
453606
|
+
scopes: ["write:sessions"],
|
|
453607
|
+
http: { method: "POST", path: "/api/companion/chat/sessions/{sessionId}/turns/cancel" },
|
|
453608
|
+
inputSchema: bodyEnvelopeSchema({
|
|
453609
|
+
sessionId: STRING_SCHEMA,
|
|
453610
|
+
turnId: STRING_SCHEMA
|
|
453611
|
+
}, ["sessionId"]),
|
|
453612
|
+
outputSchema: objectSchema({
|
|
453613
|
+
sessionId: STRING_SCHEMA,
|
|
453614
|
+
turnId: STRING_SCHEMA,
|
|
453615
|
+
cancelled: BOOLEAN_SCHEMA,
|
|
453616
|
+
alreadyCancelled: BOOLEAN_SCHEMA,
|
|
453617
|
+
partialPersisted: BOOLEAN_SCHEMA
|
|
453618
|
+
}, ["sessionId", "turnId", "cancelled", "partialPersisted"])
|
|
453619
|
+
}),
|
|
453396
453620
|
methodDescriptor({
|
|
453397
453621
|
id: "companion.chat.events.stream",
|
|
453398
453622
|
title: "Stream Companion Chat Events",
|
|
@@ -464318,6 +464542,23 @@ function createSchema2(db) {
|
|
|
464318
464542
|
)
|
|
464319
464543
|
`);
|
|
464320
464544
|
}
|
|
464545
|
+
function getKnowledgeSchemaStatements() {
|
|
464546
|
+
const statements = [];
|
|
464547
|
+
createSchema2({
|
|
464548
|
+
run(sql) {
|
|
464549
|
+
const normalized = sql.trim();
|
|
464550
|
+
if (normalized.length > 0)
|
|
464551
|
+
statements.push(normalized);
|
|
464552
|
+
}
|
|
464553
|
+
});
|
|
464554
|
+
return statements;
|
|
464555
|
+
}
|
|
464556
|
+
function renderKnowledgeSchemaSql() {
|
|
464557
|
+
return `${getKnowledgeSchemaStatements().map((statement) => statement.endsWith(";") ? statement : `${statement};`).join(`
|
|
464558
|
+
|
|
464559
|
+
`)}
|
|
464560
|
+
`;
|
|
464561
|
+
}
|
|
464321
464562
|
function rowObject(columns, values2) {
|
|
464322
464563
|
return Object.fromEntries(columns.map((column, index) => [column, values2[index]]));
|
|
464323
464564
|
}
|
|
@@ -777690,6 +777931,9 @@ var init_ingest = __esm(() => {
|
|
|
777690
777931
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/browser-history/index.js
|
|
777691
777932
|
var init_browser_history = __esm(() => {
|
|
777692
777933
|
init_ingest();
|
|
777934
|
+
init_discover();
|
|
777935
|
+
init_readers();
|
|
777936
|
+
init_paths2();
|
|
777693
777937
|
});
|
|
777694
777938
|
|
|
777695
777939
|
// node_modules/graphql/jsutils/devAssert.mjs
|
|
@@ -795564,6 +795808,7 @@ var init_semantic = __esm(() => {
|
|
|
795564
795808
|
init_llm();
|
|
795565
795809
|
init_gap_repair();
|
|
795566
795810
|
init_service5();
|
|
795811
|
+
init_self_improvement();
|
|
795567
795812
|
});
|
|
795568
795813
|
|
|
795569
795814
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/home-graph/helpers.js
|
|
@@ -799532,8 +799777,40 @@ var init_map_view = __esm(() => {
|
|
|
799532
799777
|
});
|
|
799533
799778
|
|
|
799534
799779
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/home-graph/types.js
|
|
799535
|
-
var HOME_GRAPH_CAPABILITIES;
|
|
799780
|
+
var HOME_GRAPH_NODE_KINDS, HOME_GRAPH_RELATIONS, HOME_GRAPH_CAPABILITIES;
|
|
799536
799781
|
var init_types15 = __esm(() => {
|
|
799782
|
+
HOME_GRAPH_NODE_KINDS = [
|
|
799783
|
+
"ha_home",
|
|
799784
|
+
"ha_entity",
|
|
799785
|
+
"ha_device",
|
|
799786
|
+
"ha_area",
|
|
799787
|
+
"ha_automation",
|
|
799788
|
+
"ha_script",
|
|
799789
|
+
"ha_scene",
|
|
799790
|
+
"ha_label",
|
|
799791
|
+
"ha_integration",
|
|
799792
|
+
"ha_room",
|
|
799793
|
+
"ha_device_passport",
|
|
799794
|
+
"ha_maintenance_item",
|
|
799795
|
+
"ha_troubleshooting_case",
|
|
799796
|
+
"ha_purchase",
|
|
799797
|
+
"ha_network_node"
|
|
799798
|
+
];
|
|
799799
|
+
HOME_GRAPH_RELATIONS = [
|
|
799800
|
+
"controls",
|
|
799801
|
+
"located_in",
|
|
799802
|
+
"belongs_to_device",
|
|
799803
|
+
"has_manual",
|
|
799804
|
+
"has_receipt",
|
|
799805
|
+
"has_warranty",
|
|
799806
|
+
"has_issue",
|
|
799807
|
+
"fixed_by",
|
|
799808
|
+
"uses_battery",
|
|
799809
|
+
"connected_via",
|
|
799810
|
+
"part_of_network",
|
|
799811
|
+
"mentioned_by",
|
|
799812
|
+
"source_for"
|
|
799813
|
+
];
|
|
799537
799814
|
HOME_GRAPH_CAPABILITIES = [
|
|
799538
799815
|
"knowledge-space-isolation",
|
|
799539
799816
|
"snapshot-sync",
|
|
@@ -801324,6 +801601,7 @@ var init_service6 = __esm(() => {
|
|
|
801324
801601
|
var init_home_graph = __esm(() => {
|
|
801325
801602
|
init_service6();
|
|
801326
801603
|
init_extension();
|
|
801604
|
+
init_types15();
|
|
801327
801605
|
});
|
|
801328
801606
|
|
|
801329
801607
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/store-record-delete.js
|
|
@@ -803748,10 +804026,14 @@ var init_service7 = __esm(() => {
|
|
|
803748
804026
|
var init_project_planning = __esm(() => {
|
|
803749
804027
|
init_service7();
|
|
803750
804028
|
init_helpers3();
|
|
804029
|
+
init_readiness();
|
|
803751
804030
|
});
|
|
803752
804031
|
|
|
803753
804032
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/persistence.js
|
|
803754
|
-
var init_persistence = () => {
|
|
804033
|
+
var init_persistence = __esm(() => {
|
|
804034
|
+
init_store_schema();
|
|
804035
|
+
init_store_load();
|
|
804036
|
+
});
|
|
803755
804037
|
|
|
803756
804038
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/projections.js
|
|
803757
804039
|
class KnowledgeProjectionService {
|
|
@@ -807305,21 +807587,21 @@ var init_service8 = __esm(() => {
|
|
|
807305
807587
|
var exports_knowledge = {};
|
|
807306
807588
|
__export(exports_knowledge, {
|
|
807307
807589
|
withKnowledgeSpace: () => withKnowledgeSpace,
|
|
807308
|
-
uniqKnowledgeValues: () =>
|
|
807309
|
-
stabilizeKnowledgeText: () =>
|
|
807310
|
-
runKnowledgeSemanticSelfImprovement: () =>
|
|
807590
|
+
uniqKnowledgeValues: () => uniq2,
|
|
807591
|
+
stabilizeKnowledgeText: () => stableText,
|
|
807592
|
+
runKnowledgeSemanticSelfImprovement: () => runKnowledgeSemanticSelfImprovement,
|
|
807311
807593
|
resolveProjectPlanningSpace: () => resolveProjectPlanningSpace,
|
|
807312
|
-
resolveKnowledgeDbPathFromControlPlaneDir: () =>
|
|
807594
|
+
resolveKnowledgeDbPathFromControlPlaneDir: () => resolveKnowledgeDbPathFromControlPlaneDir,
|
|
807313
807595
|
renderPacket: () => renderPacket,
|
|
807314
807596
|
renderKnowledgeSchemaSql: () => renderKnowledgeSchemaSql,
|
|
807315
807597
|
renderKnowledgeMap: () => renderKnowledgeMap,
|
|
807316
807598
|
readKnowledgeSearchText: () => readKnowledgeSearchText,
|
|
807317
|
-
readBrowserKnowledgeProfile: () =>
|
|
807599
|
+
readBrowserKnowledgeProfile: () => readBrowserKnowledgeProfile,
|
|
807318
807600
|
projectPlanningSourceId: () => projectPlanningSourceId,
|
|
807319
807601
|
projectPlanningProjectIdFromPath: () => projectPlanningProjectIdFromPath,
|
|
807320
807602
|
projectPlanningCanonicalUri: () => projectPlanningCanonicalUri,
|
|
807321
807603
|
projectKnowledgeSpaceId: () => projectKnowledgeSpaceId,
|
|
807322
|
-
parseKnowledgeJsonValue: () =>
|
|
807604
|
+
parseKnowledgeJsonValue: () => parseJsonValue,
|
|
807323
807605
|
normalizeProjectId: () => normalizeProjectId,
|
|
807324
807606
|
normalizeKnowledgeSpaceId: () => normalizeKnowledgeSpaceId,
|
|
807325
807607
|
normalizeHomeAssistantInstallationId: () => normalizeHomeAssistantInstallationId,
|
|
@@ -807327,12 +807609,12 @@ __export(exports_knowledge, {
|
|
|
807327
807609
|
materializeGeneratedKnowledgeProjection: () => materializeGeneratedKnowledgeProjection,
|
|
807328
807610
|
looksLikeRawPdfPayload: () => looksLikeRawPdfPayload,
|
|
807329
807611
|
looksBinaryLikeText: () => looksBinaryLikeText,
|
|
807330
|
-
loadKnowledgeStoreSnapshot: () =>
|
|
807612
|
+
loadKnowledgeStoreSnapshot: () => loadKnowledgeStoreSnapshot,
|
|
807331
807613
|
listGeneratedKnowledgePages: () => listGeneratedKnowledgePages,
|
|
807332
|
-
listBrowserKinds: () =>
|
|
807614
|
+
listBrowserKinds: () => listBrowserKinds,
|
|
807333
807615
|
knowledgeSpaceMetadata: () => knowledgeSpaceMetadata,
|
|
807334
807616
|
knowledgePageSourceWeight: () => knowledgePageSourceWeight,
|
|
807335
|
-
knowledgeNowMs: () =>
|
|
807617
|
+
knowledgeNowMs: () => nowMs,
|
|
807336
807618
|
knowledgeExtractionNeedsRefresh: () => knowledgeExtractionNeedsRefresh,
|
|
807337
807619
|
isUsefulKnowledgePageSourceCandidate: () => isUsefulKnowledgePageSourceCandidate,
|
|
807338
807620
|
isUsefulKnowledgePageSource: () => isUsefulKnowledgePageSource,
|
|
@@ -807352,12 +807634,12 @@ __export(exports_knowledge, {
|
|
|
807352
807634
|
generatedKnowledgeSourceId: () => generatedKnowledgeSourceId,
|
|
807353
807635
|
generatedKnowledgeCanonicalUri: () => generatedKnowledgeCanonicalUri,
|
|
807354
807636
|
extractKnowledgeArtifact: () => extractKnowledgeArtifact,
|
|
807355
|
-
evaluateProjectPlanningReadiness: () =>
|
|
807356
|
-
discoverBrowserKnowledgeProfiles: () =>
|
|
807637
|
+
evaluateProjectPlanningReadiness: () => evaluateProjectPlanningReadiness,
|
|
807638
|
+
discoverBrowserKnowledgeProfiles: () => discoverBrowserKnowledgeProfiles,
|
|
807357
807639
|
createWebKnowledgeGapRepairer: () => createWebKnowledgeGapRepairer,
|
|
807358
807640
|
createProviderBackedKnowledgeSemanticLlm: () => createProviderBackedKnowledgeSemanticLlm,
|
|
807359
807641
|
createMemoryApi: () => createMemoryApi,
|
|
807360
|
-
createKnowledgeSchema: () =>
|
|
807642
|
+
createKnowledgeSchema: () => createSchema2,
|
|
807361
807643
|
createKnowledgeApi: () => createKnowledgeApi,
|
|
807362
807644
|
createDefaultKnowledgeConnectorRegistry: () => createDefaultKnowledgeConnectorRegistry,
|
|
807363
807645
|
compareKnowledgePageSources: () => compareKnowledgePageSources,
|
|
@@ -809830,7 +810112,7 @@ var init_delivery_manager = __esm(() => {
|
|
|
809830
810112
|
});
|
|
809831
810113
|
|
|
809832
810114
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/automation/scheduler-capacity.js
|
|
809833
|
-
function computeSchedulerCapacity(slotsTotal, runs,
|
|
810115
|
+
function computeSchedulerCapacity(slotsTotal, runs, nowMs2 = Date.now()) {
|
|
809834
810116
|
let slotsInUse = 0;
|
|
809835
810117
|
const queuedRuns = [];
|
|
809836
810118
|
for (const run7 of runs) {
|
|
@@ -809840,7 +810122,7 @@ function computeSchedulerCapacity(slotsTotal, runs, nowMs3 = Date.now()) {
|
|
|
809840
810122
|
queuedRuns.push(run7);
|
|
809841
810123
|
}
|
|
809842
810124
|
const queueDepth = queuedRuns.length;
|
|
809843
|
-
const oldestQueuedAgeMs = queueDepth > 0 ?
|
|
810125
|
+
const oldestQueuedAgeMs = queueDepth > 0 ? nowMs2 - Math.min(...queuedRuns.map((r6) => r6.queuedAt)) : null;
|
|
809844
810126
|
return { slotsTotal, slotsInUse, queueDepth, oldestQueuedAgeMs };
|
|
809845
810127
|
}
|
|
809846
810128
|
|
|
@@ -813161,6 +813443,12 @@ async function dispatchCompanionChatRoutes(req, context) {
|
|
|
813161
813443
|
if (sub === "messages/edit" && req.method === "POST") {
|
|
813162
813444
|
return handleEditMessage(req, sessionId, context);
|
|
813163
813445
|
}
|
|
813446
|
+
if (sub === "turns/cancel" && req.method === "POST") {
|
|
813447
|
+
return handleCancelTurn(req, sessionId, context);
|
|
813448
|
+
}
|
|
813449
|
+
if (sub === "messages/steer" && req.method === "POST") {
|
|
813450
|
+
return handleSteerMessage(req, sessionId, context);
|
|
813451
|
+
}
|
|
813164
813452
|
if (sub === "events" && req.method === "GET") {
|
|
813165
813453
|
return handleGetEvents(req, sessionId, context);
|
|
813166
813454
|
}
|
|
@@ -813417,6 +813705,42 @@ async function handleGetMessages(sessionId, context) {
|
|
|
813417
813705
|
const messages = context.chatManager.getMessages(sessionId);
|
|
813418
813706
|
return Response.json({ sessionId, messages });
|
|
813419
813707
|
}
|
|
813708
|
+
async function handleCancelTurn(req, sessionId, context) {
|
|
813709
|
+
const bodyOrResponse = await context.parseOptionalJsonBody(req);
|
|
813710
|
+
if (bodyOrResponse instanceof Response)
|
|
813711
|
+
return bodyOrResponse;
|
|
813712
|
+
const body2 = bodyOrResponse ?? {};
|
|
813713
|
+
const input = {
|
|
813714
|
+
turnId: typeof body2["turnId"] === "string" && body2["turnId"].trim() ? body2["turnId"].trim() : undefined
|
|
813715
|
+
};
|
|
813716
|
+
try {
|
|
813717
|
+
return Response.json(await context.chatManager.cancelTurn(sessionId, input));
|
|
813718
|
+
} catch (err2) {
|
|
813719
|
+
return respondWithManagerError(err2);
|
|
813720
|
+
}
|
|
813721
|
+
}
|
|
813722
|
+
async function handleSteerMessage(req, sessionId, context) {
|
|
813723
|
+
const bodyOrResponse = await context.parseJsonBody(req);
|
|
813724
|
+
if (bodyOrResponse instanceof Response)
|
|
813725
|
+
return bodyOrResponse;
|
|
813726
|
+
const body2 = bodyOrResponse;
|
|
813727
|
+
const rawContent = readCompanionChatMessageBody(body2);
|
|
813728
|
+
const attachments = readCompanionChatAttachments(body2);
|
|
813729
|
+
if (attachments instanceof Response)
|
|
813730
|
+
return attachments;
|
|
813731
|
+
if (!rawContent.trim() && attachments.length === 0) {
|
|
813732
|
+
return Response.json({ error: "content, body, or attachments are required", code: "INVALID_INPUT" }, { status: 400 });
|
|
813733
|
+
}
|
|
813734
|
+
try {
|
|
813735
|
+
const result = await context.chatManager.steerMessage(sessionId, rawContent, "", {
|
|
813736
|
+
attachments,
|
|
813737
|
+
metadata: typeof body2["metadata"] === "object" && body2["metadata"] !== null ? body2["metadata"] : undefined
|
|
813738
|
+
});
|
|
813739
|
+
return Response.json(result, { status: 202 });
|
|
813740
|
+
} catch (err2) {
|
|
813741
|
+
return respondWithManagerError(err2);
|
|
813742
|
+
}
|
|
813743
|
+
}
|
|
813420
813744
|
async function handleGetEvents(req, sessionId, context) {
|
|
813421
813745
|
const session2 = context.chatManager.getSession(sessionId);
|
|
813422
813746
|
if (!session2) {
|
|
@@ -814619,7 +814943,7 @@ class HomeAssistantConversationRoutes {
|
|
|
814619
814943
|
const body2 = await this.context.parseJsonBody(req);
|
|
814620
814944
|
if (body2 instanceof Response)
|
|
814621
814945
|
return body2;
|
|
814622
|
-
return this.cancelConversation(body2);
|
|
814946
|
+
return await this.cancelConversation(body2);
|
|
814623
814947
|
}
|
|
814624
814948
|
return null;
|
|
814625
814949
|
}
|
|
@@ -814805,14 +815129,24 @@ data: ${JSON.stringify(data)}
|
|
|
814805
815129
|
}
|
|
814806
815130
|
});
|
|
814807
815131
|
}
|
|
814808
|
-
cancelConversation(body2) {
|
|
815132
|
+
async cancelConversation(body2) {
|
|
814809
815133
|
const indexed = readString27(body2.messageId ?? body2.message_id) ? this.messageIndex.get(readString27(body2.messageId ?? body2.message_id)) : undefined;
|
|
814810
815134
|
const sessionId = readString27(body2.sessionId ?? body2.session_id) ?? indexed?.sessionId;
|
|
814811
815135
|
if (!sessionId) {
|
|
814812
815136
|
return Response.json({ ok: false, error: "sessionId or known messageId is required." }, { status: 400 });
|
|
814813
815137
|
}
|
|
814814
|
-
|
|
814815
|
-
|
|
815138
|
+
if (!this.context.chatManager.getSession(sessionId)) {
|
|
815139
|
+
return Response.json({ ok: false, sessionId, error: "Unknown Home Assistant chat session." }, { status: 404 });
|
|
815140
|
+
}
|
|
815141
|
+
try {
|
|
815142
|
+
await this.context.chatManager.cancelTurn(sessionId);
|
|
815143
|
+
} catch (error51) {
|
|
815144
|
+
const code2 = error51.code;
|
|
815145
|
+
if (code2 !== "NO_ACTIVE_TURN") {
|
|
815146
|
+
return Response.json({ ok: false, sessionId, error: error51 instanceof Error ? error51.message : String(error51) }, { status: 500 });
|
|
815147
|
+
}
|
|
815148
|
+
}
|
|
815149
|
+
return Response.json({ ok: true, sessionId, status: "cancelled" });
|
|
814816
815150
|
}
|
|
814817
815151
|
parseInput(body2) {
|
|
814818
815152
|
const threadId = readString27(body2.threadId ?? body2.thread_id);
|
|
@@ -816957,6 +817291,135 @@ var init_companion_chat_rate_limiter = __esm(() => {
|
|
|
816957
817291
|
init_dist();
|
|
816958
817292
|
});
|
|
816959
817293
|
|
|
817294
|
+
// node_modules/@pellux/goodvibes-sdk/dist/platform/companion/companion-chat-turn-control.js
|
|
817295
|
+
function createTurnAbortScope(turnId, sessionSignal) {
|
|
817296
|
+
const controller = new AbortController;
|
|
817297
|
+
const onSessionAbort = () => {
|
|
817298
|
+
controller.abort();
|
|
817299
|
+
};
|
|
817300
|
+
if (sessionSignal.aborted)
|
|
817301
|
+
controller.abort();
|
|
817302
|
+
else
|
|
817303
|
+
sessionSignal.addEventListener("abort", onSessionAbort, { once: true });
|
|
817304
|
+
let settle;
|
|
817305
|
+
const settled = new Promise((resolve31) => {
|
|
817306
|
+
settle = resolve31;
|
|
817307
|
+
});
|
|
817308
|
+
const activeTurn = { turnId, controller, cancelRequested: false, settled };
|
|
817309
|
+
return {
|
|
817310
|
+
activeTurn,
|
|
817311
|
+
abortSignal: controller.signal,
|
|
817312
|
+
settle,
|
|
817313
|
+
detach: () => {
|
|
817314
|
+
sessionSignal.removeEventListener("abort", onSessionAbort);
|
|
817315
|
+
}
|
|
817316
|
+
};
|
|
817317
|
+
}
|
|
817318
|
+
function finalizeCancelledTurn(ctx) {
|
|
817319
|
+
const { sessionId, turnId } = ctx;
|
|
817320
|
+
const stoppedBy = ctx.wasCancelRequested() ? "user" : ctx.isShutdown() ? "shutdown" : "session-closed";
|
|
817321
|
+
for (const [toolCallId, toolName] of ctx.openToolCalls) {
|
|
817322
|
+
ctx.publish({
|
|
817323
|
+
type: "turn.tool_result",
|
|
817324
|
+
sessionId,
|
|
817325
|
+
turnId,
|
|
817326
|
+
toolCallId,
|
|
817327
|
+
toolName,
|
|
817328
|
+
result: "Cancelled: the turn was stopped before this tool call completed.",
|
|
817329
|
+
isError: true
|
|
817330
|
+
});
|
|
817331
|
+
}
|
|
817332
|
+
ctx.openToolCalls.clear();
|
|
817333
|
+
const assistantContent = ctx.getAssistantContent();
|
|
817334
|
+
const uncommitted = ctx.getUncommittedContent();
|
|
817335
|
+
if (uncommitted.trim()) {
|
|
817336
|
+
ctx.commitPartialToHistory(uncommitted + TURN_INTERRUPTION_NOTE);
|
|
817337
|
+
}
|
|
817338
|
+
let persistedId;
|
|
817339
|
+
let envelope;
|
|
817340
|
+
if (assistantContent.trim()) {
|
|
817341
|
+
const now4 = Date.now();
|
|
817342
|
+
ctx.persistPartial({
|
|
817343
|
+
id: ctx.assistantMessageId,
|
|
817344
|
+
sessionId,
|
|
817345
|
+
role: "assistant",
|
|
817346
|
+
content: assistantContent,
|
|
817347
|
+
attachments: [],
|
|
817348
|
+
createdAt: now4,
|
|
817349
|
+
deliveryState: "cancelled",
|
|
817350
|
+
inReplyTo: ctx.userMessageId
|
|
817351
|
+
});
|
|
817352
|
+
persistedId = ctx.assistantMessageId;
|
|
817353
|
+
envelope = {
|
|
817354
|
+
sessionId,
|
|
817355
|
+
messageId: ctx.assistantMessageId,
|
|
817356
|
+
body: assistantContent,
|
|
817357
|
+
source: "companion-chat-assistant",
|
|
817358
|
+
timestamp: now4
|
|
817359
|
+
};
|
|
817360
|
+
}
|
|
817361
|
+
ctx.publish({
|
|
817362
|
+
type: "turn.cancelled",
|
|
817363
|
+
sessionId,
|
|
817364
|
+
turnId,
|
|
817365
|
+
stoppedBy,
|
|
817366
|
+
partialPersisted: persistedId !== undefined,
|
|
817367
|
+
...persistedId !== undefined ? { assistantMessageId: persistedId, envelope } : {}
|
|
817368
|
+
});
|
|
817369
|
+
ctx.resolveReply(persistedId !== undefined ? { assistantMessageId: persistedId, response: assistantContent } : {});
|
|
817370
|
+
ctx.settle({
|
|
817371
|
+
partialPersisted: persistedId !== undefined,
|
|
817372
|
+
...persistedId !== undefined ? { assistantMessageId: persistedId } : {}
|
|
817373
|
+
});
|
|
817374
|
+
}
|
|
817375
|
+
async function cancelActiveTurn(sessionId, turn2, input) {
|
|
817376
|
+
if (!turn2) {
|
|
817377
|
+
throw Object.assign(new Error("No turn is in flight for this session \u2014 it may have finished before the stop landed."), { code: "NO_ACTIVE_TURN", status: 404 });
|
|
817378
|
+
}
|
|
817379
|
+
if (input.turnId !== undefined && input.turnId !== turn2.turnId) {
|
|
817380
|
+
throw Object.assign(new Error("The requested turn is not the active turn \u2014 a newer turn is already running."), { code: "TURN_MISMATCH", status: 409 });
|
|
817381
|
+
}
|
|
817382
|
+
const alreadyCancelled = turn2.cancelRequested;
|
|
817383
|
+
if (!alreadyCancelled) {
|
|
817384
|
+
turn2.cancelRequested = true;
|
|
817385
|
+
turn2.controller.abort();
|
|
817386
|
+
}
|
|
817387
|
+
const settled = await Promise.race([
|
|
817388
|
+
turn2.settled,
|
|
817389
|
+
new Promise((resolve31) => setTimeout(resolve31, CANCEL_SETTLE_TIMEOUT_MS))
|
|
817390
|
+
]);
|
|
817391
|
+
return {
|
|
817392
|
+
sessionId,
|
|
817393
|
+
turnId: turn2.turnId,
|
|
817394
|
+
cancelled: true,
|
|
817395
|
+
...alreadyCancelled ? { alreadyCancelled: true } : {},
|
|
817396
|
+
partialPersisted: settled?.partialPersisted ?? false
|
|
817397
|
+
};
|
|
817398
|
+
}
|
|
817399
|
+
function awaitCompanionReply(timeoutMs, post, onTimeout) {
|
|
817400
|
+
let messageId = "";
|
|
817401
|
+
return new Promise((resolve31) => {
|
|
817402
|
+
const timeout = setTimeout(() => {
|
|
817403
|
+
if (messageId)
|
|
817404
|
+
onTimeout(messageId);
|
|
817405
|
+
resolve31({ messageId, error: "Timed out waiting for companion chat reply" });
|
|
817406
|
+
}, timeoutMs);
|
|
817407
|
+
timeout.unref?.();
|
|
817408
|
+
post({ resolve: resolve31, timeout }).then((id) => {
|
|
817409
|
+
messageId = id;
|
|
817410
|
+
}).catch((error51) => {
|
|
817411
|
+
clearTimeout(timeout);
|
|
817412
|
+
resolve31({
|
|
817413
|
+
messageId,
|
|
817414
|
+
error: error51 instanceof Error ? error51.message : String(error51)
|
|
817415
|
+
});
|
|
817416
|
+
});
|
|
817417
|
+
});
|
|
817418
|
+
}
|
|
817419
|
+
var TURN_INTERRUPTION_NOTE = `
|
|
817420
|
+
|
|
817421
|
+
[Interrupted: the user stopped this response here, before it was complete.]`, CANCEL_SETTLE_TIMEOUT_MS = 3000;
|
|
817422
|
+
|
|
816960
817423
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/companion/companion-chat-manager.js
|
|
816961
817424
|
import { randomUUID as randomUUID43 } from "crypto";
|
|
816962
817425
|
function assertCompleteProviderModelRoute(input) {
|
|
@@ -816987,6 +817450,7 @@ class CompanionChatManager {
|
|
|
816987
817450
|
gcTimer = null;
|
|
816988
817451
|
initCompleted = false;
|
|
816989
817452
|
pendingReplies = new Map;
|
|
817453
|
+
disposed = false;
|
|
816990
817454
|
_pendingSaves = new Map;
|
|
816991
817455
|
constructor(config6) {
|
|
816992
817456
|
this.provider = config6.provider;
|
|
@@ -817140,6 +817604,13 @@ class CompanionChatManager {
|
|
|
817140
817604
|
this._brokerSync.track(sessionId, () => this._brokerSync.closeSession(sessionId));
|
|
817141
817605
|
return updated;
|
|
817142
817606
|
}
|
|
817607
|
+
async cancelTurn(sessionId, input = {}) {
|
|
817608
|
+
const session2 = this.sessions.get(sessionId);
|
|
817609
|
+
if (!session2) {
|
|
817610
|
+
throw Object.assign(new Error(`Session not found: ${sessionId}`), { code: "SESSION_NOT_FOUND", status: 404 });
|
|
817611
|
+
}
|
|
817612
|
+
return cancelActiveTurn(sessionId, session2.activeTurn ?? null, input);
|
|
817613
|
+
}
|
|
817143
817614
|
async deleteSession(sessionId) {
|
|
817144
817615
|
const session2 = this.sessions.get(sessionId);
|
|
817145
817616
|
if (!session2) {
|
|
@@ -817160,29 +817631,11 @@ class CompanionChatManager {
|
|
|
817160
817631
|
});
|
|
817161
817632
|
}
|
|
817162
817633
|
async postMessageAndWaitForReply(sessionId, content, clientId = "", options = {}) {
|
|
817163
|
-
|
|
817164
|
-
|
|
817165
|
-
|
|
817166
|
-
|
|
817167
|
-
|
|
817168
|
-
resolve31({ messageId, error: "Timed out waiting for companion chat reply" });
|
|
817169
|
-
}, options.timeoutMs ?? 120000);
|
|
817170
|
-
timeout.unref?.();
|
|
817171
|
-
this._postMessageInternal(sessionId, content, clientId, {
|
|
817172
|
-
pendingReply: { resolve: resolve31, timeout },
|
|
817173
|
-
attachments: options.attachments,
|
|
817174
|
-
...options.onTurnEvent ? { onTurnEvent: options.onTurnEvent } : {}
|
|
817175
|
-
}).then((id) => {
|
|
817176
|
-
messageId = id;
|
|
817177
|
-
}).catch((error51) => {
|
|
817178
|
-
clearTimeout(timeout);
|
|
817179
|
-
resolve31({
|
|
817180
|
-
messageId,
|
|
817181
|
-
error: error51 instanceof Error ? error51.message : String(error51)
|
|
817182
|
-
});
|
|
817183
|
-
});
|
|
817184
|
-
});
|
|
817185
|
-
return result;
|
|
817634
|
+
return awaitCompanionReply(options.timeoutMs ?? 120000, (pendingReply) => this._postMessageInternal(sessionId, content, clientId, {
|
|
817635
|
+
pendingReply,
|
|
817636
|
+
attachments: options.attachments,
|
|
817637
|
+
...options.onTurnEvent ? { onTurnEvent: options.onTurnEvent } : {}
|
|
817638
|
+
}), (messageId) => this.pendingReplies.delete(messageId));
|
|
817186
817639
|
}
|
|
817187
817640
|
async _postMessageInternal(sessionId, content, clientId, options = {}) {
|
|
817188
817641
|
const session2 = this.sessions.get(sessionId);
|
|
@@ -817199,6 +817652,7 @@ class CompanionChatManager {
|
|
|
817199
817652
|
}
|
|
817200
817653
|
const messageId = randomUUID43();
|
|
817201
817654
|
const now4 = Date.now();
|
|
817655
|
+
const queuedBehindActiveTurn = session2.activeTurn != null && options.steer !== true;
|
|
817202
817656
|
const userMsg = {
|
|
817203
817657
|
id: messageId,
|
|
817204
817658
|
sessionId,
|
|
@@ -817206,10 +817660,11 @@ class CompanionChatManager {
|
|
|
817206
817660
|
content,
|
|
817207
817661
|
attachments,
|
|
817208
817662
|
...options.metadata !== undefined ? { metadata: options.metadata } : {},
|
|
817209
|
-
createdAt: now4
|
|
817663
|
+
createdAt: now4,
|
|
817664
|
+
...queuedBehindActiveTurn ? { deliveryState: "queued" } : {}
|
|
817210
817665
|
};
|
|
817666
|
+
const providerContent = await buildProviderUserContent(content, attachments, this.artifactStore);
|
|
817211
817667
|
session2.messages.push(userMsg);
|
|
817212
|
-
session2.conversation.addUserMessage(await buildProviderUserContent(content, attachments, this.artifactStore));
|
|
817213
817668
|
session2.lastActivityAt = now4;
|
|
817214
817669
|
this._updateMeta(session2, {
|
|
817215
817670
|
messageCount: session2.messages.length,
|
|
@@ -817219,16 +817674,21 @@ class CompanionChatManager {
|
|
|
817219
817674
|
if (options.pendingReply) {
|
|
817220
817675
|
this.pendingReplies.set(messageId, options.pendingReply);
|
|
817221
817676
|
}
|
|
817222
|
-
|
|
817223
|
-
|
|
817224
|
-
|
|
817225
|
-
|
|
817226
|
-
|
|
817227
|
-
|
|
817228
|
-
|
|
817677
|
+
const entry = {
|
|
817678
|
+
userMessageId: messageId,
|
|
817679
|
+
providerContent,
|
|
817680
|
+
...options.onTurnEvent ? { onTurnEvent: options.onTurnEvent } : {}
|
|
817681
|
+
};
|
|
817682
|
+
const queue = session2.pendingTurns ??= [];
|
|
817683
|
+
if (options.steer === true)
|
|
817684
|
+
queue.unshift(entry);
|
|
817685
|
+
else
|
|
817686
|
+
queue.push(entry);
|
|
817687
|
+
this._startNextTurn(session2);
|
|
817229
817688
|
return messageId;
|
|
817230
817689
|
}
|
|
817231
817690
|
dispose() {
|
|
817691
|
+
this.disposed = true;
|
|
817232
817692
|
if (this.gcTimer) {
|
|
817233
817693
|
clearInterval(this.gcTimer);
|
|
817234
817694
|
this.gcTimer = null;
|
|
@@ -817238,11 +817698,70 @@ class CompanionChatManager {
|
|
|
817238
817698
|
}
|
|
817239
817699
|
this.sessions.clear();
|
|
817240
817700
|
}
|
|
817701
|
+
async steerMessage(sessionId, content, clientId = "", options = {}) {
|
|
817702
|
+
const activeBefore = this.sessions.get(sessionId)?.activeTurn ?? null;
|
|
817703
|
+
const messageId = await this._postMessageInternal(sessionId, content, clientId, {
|
|
817704
|
+
attachments: options.attachments,
|
|
817705
|
+
metadata: options.metadata,
|
|
817706
|
+
steer: true
|
|
817707
|
+
});
|
|
817708
|
+
let cancelledTurnId;
|
|
817709
|
+
if (activeBefore) {
|
|
817710
|
+
try {
|
|
817711
|
+
const result = await this.cancelTurn(sessionId, { turnId: activeBefore.turnId });
|
|
817712
|
+
cancelledTurnId = result.turnId;
|
|
817713
|
+
} catch (err2) {
|
|
817714
|
+
const code2 = err2.code;
|
|
817715
|
+
if (code2 !== "NO_ACTIVE_TURN" && code2 !== "TURN_MISMATCH")
|
|
817716
|
+
throw err2;
|
|
817717
|
+
}
|
|
817718
|
+
}
|
|
817719
|
+
const session2 = this.sessions.get(sessionId);
|
|
817720
|
+
if (session2)
|
|
817721
|
+
this._startNextTurn(session2);
|
|
817722
|
+
return {
|
|
817723
|
+
sessionId,
|
|
817724
|
+
messageId,
|
|
817725
|
+
steered: true,
|
|
817726
|
+
...cancelledTurnId !== undefined ? { cancelledTurnId } : {},
|
|
817727
|
+
turnStarted: true
|
|
817728
|
+
};
|
|
817729
|
+
}
|
|
817730
|
+
_startNextTurn(session2) {
|
|
817731
|
+
if (session2.activeTurn || session2.meta.status === "closed")
|
|
817732
|
+
return;
|
|
817733
|
+
const next = session2.pendingTurns?.shift();
|
|
817734
|
+
if (!next)
|
|
817735
|
+
return;
|
|
817736
|
+
const idx = session2.messages.findIndex((m3) => m3.id === next.userMessageId);
|
|
817737
|
+
const queuedMsg = idx >= 0 ? session2.messages[idx] : undefined;
|
|
817738
|
+
if (queuedMsg?.deliveryState === "queued") {
|
|
817739
|
+
const { deliveryState: _cleared, ...delivered } = queuedMsg;
|
|
817740
|
+
session2.messages[idx] = delivered;
|
|
817741
|
+
this._persist(session2.meta.id);
|
|
817742
|
+
}
|
|
817743
|
+
session2.conversation.addUserMessage(next.providerContent);
|
|
817744
|
+
this._runTurn(session2, next.userMessageId, next.onTurnEvent).catch((error51) => {
|
|
817745
|
+
logger.warn("[companion-chat] turn execution failed", {
|
|
817746
|
+
sessionId: session2.meta.id,
|
|
817747
|
+
messageId: next.userMessageId,
|
|
817748
|
+
error: summarizeError(error51)
|
|
817749
|
+
});
|
|
817750
|
+
});
|
|
817751
|
+
}
|
|
817241
817752
|
async _runTurn(session2, userMessageId, onTurnEvent) {
|
|
817242
817753
|
const turnId = randomUUID43();
|
|
817243
817754
|
const sessionId = session2.meta.id;
|
|
817244
|
-
const
|
|
817755
|
+
const scope = createTurnAbortScope(turnId, session2.abortController.signal);
|
|
817756
|
+
const abortSignal = scope.abortSignal;
|
|
817757
|
+
session2.activeTurn = scope.activeTurn;
|
|
817758
|
+
const openToolCalls = new Map;
|
|
817245
817759
|
const publish = (event) => {
|
|
817760
|
+
if (event.type === "turn.tool_call" && event.toolCallId) {
|
|
817761
|
+
openToolCalls.set(event.toolCallId, event.toolName);
|
|
817762
|
+
} else if (event.type === "turn.tool_result" && event.toolCallId) {
|
|
817763
|
+
openToolCalls.delete(event.toolCallId);
|
|
817764
|
+
}
|
|
817246
817765
|
this.eventPublisher.publishEvent(`companion-chat.${event.type}`, event, session2.subscriberClientId ? { clientId: session2.subscriberClientId } : undefined);
|
|
817247
817766
|
try {
|
|
817248
817767
|
onTurnEvent?.(event);
|
|
@@ -817259,7 +817778,31 @@ class CompanionChatManager {
|
|
|
817259
817778
|
};
|
|
817260
817779
|
publish({ type: "turn.started", sessionId, messageId: userMessageId, turnId, envelope: startEnvelope });
|
|
817261
817780
|
let assistantContent = "";
|
|
817781
|
+
let uncommittedContent = "";
|
|
817262
817782
|
const assistantMessageId = randomUUID43();
|
|
817783
|
+
const finalizeCancelled = () => finalizeCancelledTurn({
|
|
817784
|
+
sessionId,
|
|
817785
|
+
turnId,
|
|
817786
|
+
assistantMessageId,
|
|
817787
|
+
userMessageId,
|
|
817788
|
+
getAssistantContent: () => assistantContent,
|
|
817789
|
+
getUncommittedContent: () => uncommittedContent,
|
|
817790
|
+
commitPartialToHistory: (content) => {
|
|
817791
|
+
session2.conversation.addAssistantMessage(content);
|
|
817792
|
+
},
|
|
817793
|
+
openToolCalls,
|
|
817794
|
+
wasCancelRequested: () => scope.activeTurn.cancelRequested,
|
|
817795
|
+
isShutdown: () => this.disposed,
|
|
817796
|
+
publish,
|
|
817797
|
+
persistPartial: (message) => {
|
|
817798
|
+
session2.messages.push(message);
|
|
817799
|
+
session2.lastActivityAt = message.createdAt;
|
|
817800
|
+
this._updateMeta(session2, { messageCount: session2.messages.length, updatedAt: message.createdAt });
|
|
817801
|
+
this._persist(sessionId);
|
|
817802
|
+
},
|
|
817803
|
+
resolveReply: (extra) => this.resolvePendingReply(userMessageId, { messageId: userMessageId, ...extra, error: "Turn cancelled" }),
|
|
817804
|
+
settle: scope.settle
|
|
817805
|
+
});
|
|
817263
817806
|
try {
|
|
817264
817807
|
const toolDefinitions = this.toolRegistry?.getToolDefinitions() ?? [];
|
|
817265
817808
|
let completed = false;
|
|
@@ -817271,7 +817814,7 @@ class CompanionChatManager {
|
|
|
817271
817814
|
tools: toolDefinitions,
|
|
817272
817815
|
abortSignal
|
|
817273
817816
|
});
|
|
817274
|
-
|
|
817817
|
+
uncommittedContent = "";
|
|
817275
817818
|
const toolCalls = [];
|
|
817276
817819
|
for await (const chunk of stream6) {
|
|
817277
817820
|
if (abortSignal.aborted)
|
|
@@ -817279,7 +817822,7 @@ class CompanionChatManager {
|
|
|
817279
817822
|
switch (chunk.type) {
|
|
817280
817823
|
case "text_delta": {
|
|
817281
817824
|
const delta = chunk.delta ?? "";
|
|
817282
|
-
|
|
817825
|
+
uncommittedContent += delta;
|
|
817283
817826
|
assistantContent += delta;
|
|
817284
817827
|
publish({ type: "turn.delta", sessionId, turnId, delta });
|
|
817285
817828
|
break;
|
|
@@ -817323,11 +817866,13 @@ class CompanionChatManager {
|
|
|
817323
817866
|
if (abortSignal.aborted)
|
|
817324
817867
|
break;
|
|
817325
817868
|
if (toolCalls.length === 0) {
|
|
817326
|
-
session2.conversation.addAssistantMessage(
|
|
817869
|
+
session2.conversation.addAssistantMessage(uncommittedContent);
|
|
817870
|
+
uncommittedContent = "";
|
|
817327
817871
|
completed = true;
|
|
817328
817872
|
break;
|
|
817329
817873
|
}
|
|
817330
|
-
session2.conversation.addAssistantMessage(
|
|
817874
|
+
session2.conversation.addAssistantMessage(uncommittedContent, { toolCalls });
|
|
817875
|
+
uncommittedContent = "";
|
|
817331
817876
|
if (!this.toolRegistry) {
|
|
817332
817877
|
completed = true;
|
|
817333
817878
|
break;
|
|
@@ -817349,7 +817894,7 @@ class CompanionChatManager {
|
|
|
817349
817894
|
}
|
|
817350
817895
|
}
|
|
817351
817896
|
if (abortSignal.aborted) {
|
|
817352
|
-
|
|
817897
|
+
finalizeCancelled();
|
|
817353
817898
|
return;
|
|
817354
817899
|
}
|
|
817355
817900
|
const now4 = Date.now();
|
|
@@ -817359,7 +817904,8 @@ class CompanionChatManager {
|
|
|
817359
817904
|
role: "assistant",
|
|
817360
817905
|
content: assistantContent,
|
|
817361
817906
|
attachments: [],
|
|
817362
|
-
createdAt: now4
|
|
817907
|
+
createdAt: now4,
|
|
817908
|
+
inReplyTo: userMessageId
|
|
817363
817909
|
};
|
|
817364
817910
|
session2.messages.push(assistantMsg);
|
|
817365
817911
|
session2.lastActivityAt = now4;
|
|
@@ -817380,8 +817926,14 @@ class CompanionChatManager {
|
|
|
817380
817926
|
publish({ type: "turn.error", sessionId, turnId, error: errorMessage });
|
|
817381
817927
|
this.resolvePendingReply(userMessageId, { messageId: userMessageId, error: errorMessage });
|
|
817382
817928
|
} else {
|
|
817383
|
-
|
|
817929
|
+
finalizeCancelled();
|
|
817384
817930
|
}
|
|
817931
|
+
} finally {
|
|
817932
|
+
if (session2.activeTurn === scope.activeTurn)
|
|
817933
|
+
session2.activeTurn = null;
|
|
817934
|
+
scope.detach();
|
|
817935
|
+
scope.settle({ partialPersisted: false });
|
|
817936
|
+
this._startNextTurn(session2);
|
|
817385
817937
|
}
|
|
817386
817938
|
}
|
|
817387
817939
|
regenerateMessage(sessionId, input = {}) {
|
|
@@ -837066,7 +837618,7 @@ var createStyledCell = (char, overrides = {}) => ({
|
|
|
837066
837618
|
// src/version.ts
|
|
837067
837619
|
import { readFileSync } from "fs";
|
|
837068
837620
|
import { join } from "path";
|
|
837069
|
-
var _version = "1.6.
|
|
837621
|
+
var _version = "1.6.3";
|
|
837070
837622
|
try {
|
|
837071
837623
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, "..", "package.json"), "utf-8"));
|
|
837072
837624
|
_version = typeof pkg.version === "string" ? pkg.version : _version;
|
|
@@ -862223,7 +862775,7 @@ var WORK_PLAN_STATUSES = [
|
|
|
862223
862775
|
"failed",
|
|
862224
862776
|
"cancelled"
|
|
862225
862777
|
];
|
|
862226
|
-
function
|
|
862778
|
+
function nowMs2() {
|
|
862227
862779
|
return Date.now();
|
|
862228
862780
|
}
|
|
862229
862781
|
function isObject4(value) {
|
|
@@ -862329,7 +862881,7 @@ class WorkPlanStore {
|
|
|
862329
862881
|
if (!normalizedTitle)
|
|
862330
862882
|
throw new Error("Work plan item title is required.");
|
|
862331
862883
|
const plan = this.readPlan();
|
|
862332
|
-
const time4 =
|
|
862884
|
+
const time4 = nowMs2();
|
|
862333
862885
|
const item = {
|
|
862334
862886
|
id: createItemId(),
|
|
862335
862887
|
title: normalizedTitle,
|
|
@@ -862353,7 +862905,7 @@ class WorkPlanStore {
|
|
|
862353
862905
|
updateItem(idOrPrefix, patch2) {
|
|
862354
862906
|
const plan = this.readPlan();
|
|
862355
862907
|
const item = this.resolveItem(plan, idOrPrefix);
|
|
862356
|
-
const time4 =
|
|
862908
|
+
const time4 = nowMs2();
|
|
862357
862909
|
const nextStatus = patch2.status ?? item.status;
|
|
862358
862910
|
const next = this.pruneItem({
|
|
862359
862911
|
...item,
|
|
@@ -862386,7 +862938,7 @@ class WorkPlanStore {
|
|
|
862386
862938
|
removeItem(idOrPrefix) {
|
|
862387
862939
|
const plan = this.readPlan();
|
|
862388
862940
|
const item = this.resolveItem(plan, idOrPrefix);
|
|
862389
|
-
const time4 =
|
|
862941
|
+
const time4 = nowMs2();
|
|
862390
862942
|
const remaining = plan.items.filter((candidate) => candidate.id !== item.id);
|
|
862391
862943
|
this.writePlan({
|
|
862392
862944
|
...plan,
|
|
@@ -862406,7 +862958,7 @@ class WorkPlanStore {
|
|
|
862406
862958
|
...plan,
|
|
862407
862959
|
items: remaining,
|
|
862408
862960
|
activeItemId: remaining[0]?.id,
|
|
862409
|
-
updatedAt:
|
|
862961
|
+
updatedAt: nowMs2()
|
|
862410
862962
|
});
|
|
862411
862963
|
return removed;
|
|
862412
862964
|
}
|
|
@@ -862445,7 +862997,7 @@ class WorkPlanStore {
|
|
|
862445
862997
|
const parsed = JSON.parse(raw);
|
|
862446
862998
|
if (!isObject4(parsed))
|
|
862447
862999
|
return this.createEmptyPlan();
|
|
862448
|
-
const time4 =
|
|
863000
|
+
const time4 = nowMs2();
|
|
862449
863001
|
const createdAt = typeof parsed.createdAt === "number" ? parsed.createdAt : time4;
|
|
862450
863002
|
const updatedAt = typeof parsed.updatedAt === "number" ? parsed.updatedAt : createdAt;
|
|
862451
863003
|
const items = Array.isArray(parsed.items) ? parsed.items.map((item) => normalizeItem(item, createdAt)).filter((item) => item !== null) : [];
|
|
@@ -862464,7 +863016,7 @@ class WorkPlanStore {
|
|
|
862464
863016
|
};
|
|
862465
863017
|
}
|
|
862466
863018
|
createEmptyPlan() {
|
|
862467
|
-
const time4 =
|
|
863019
|
+
const time4 = nowMs2();
|
|
862468
863020
|
return {
|
|
862469
863021
|
id: createPlanId(this.options.projectId, this.options.projectRoot),
|
|
862470
863022
|
projectId: this.options.projectId,
|
|
@@ -869724,7 +870276,11 @@ function createBrowserKnowledgeSdkFromRoutes(knowledgeRoutes, options = {}) {
|
|
|
869724
870276
|
},
|
|
869725
870277
|
messages: {
|
|
869726
870278
|
create: (id, input) => invoke("companion.chat.messages.create", { sessionId: id, ...input }),
|
|
869727
|
-
list: (id) => invoke("companion.chat.messages.list", { sessionId: id })
|
|
870279
|
+
list: (id) => invoke("companion.chat.messages.list", { sessionId: id }),
|
|
870280
|
+
steer: (id, input) => invoke("companion.chat.messages.steer", { sessionId: id, ...input })
|
|
870281
|
+
},
|
|
870282
|
+
turns: {
|
|
870283
|
+
cancel: (id, input) => invoke("companion.chat.turns.cancel", { sessionId: id, ...input ?? {} })
|
|
869728
870284
|
},
|
|
869729
870285
|
events: {
|
|
869730
870286
|
stream: (id, handlers, options2) => sdk.streams.open("/api/companion/chat/sessions/" + id + "/events", handlers, options2)
|
|
@@ -894274,13 +894830,13 @@ init_state();
|
|
|
894274
894830
|
|
|
894275
894831
|
// src/input/commands/recall-shared.ts
|
|
894276
894832
|
var VALID_CLASSES = ["decision", "constraint", "incident", "pattern", "fact", "risk", "runbook", "architecture", "ownership"];
|
|
894277
|
-
var
|
|
894833
|
+
var VALID_SCOPES = ["session", "project", "team"];
|
|
894278
894834
|
var VALID_REVIEW_STATES = ["fresh", "reviewed", "stale", "contradicted"];
|
|
894279
894835
|
function isValidClass(s4) {
|
|
894280
894836
|
return VALID_CLASSES.includes(s4);
|
|
894281
894837
|
}
|
|
894282
894838
|
function isValidScope(s4) {
|
|
894283
|
-
return
|
|
894839
|
+
return VALID_SCOPES.includes(s4);
|
|
894284
894840
|
}
|
|
894285
894841
|
function isValidReviewState(s4) {
|
|
894286
894842
|
return VALID_REVIEW_STATES.includes(s4);
|
|
@@ -894323,7 +894879,7 @@ function handleRecallSearch(args2, context) {
|
|
|
894323
894879
|
if (isValidScope(scope))
|
|
894324
894880
|
filter.scope = scope;
|
|
894325
894881
|
else {
|
|
894326
|
-
context.print(`[memory] Unknown scope "${scope}". Valid values ${
|
|
894882
|
+
context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
894327
894883
|
return;
|
|
894328
894884
|
}
|
|
894329
894885
|
}
|
|
@@ -894498,7 +895054,7 @@ function handleRecallList(args2, context) {
|
|
|
894498
895054
|
if (scopeIdx !== -1 && args2[scopeIdx + 1]) {
|
|
894499
895055
|
const scope = args2[scopeIdx + 1];
|
|
894500
895056
|
if (!isValidScope(scope)) {
|
|
894501
|
-
context.print(`[memory] Unknown scope "${scope}". Valid values ${
|
|
895057
|
+
context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
894502
895058
|
return;
|
|
894503
895059
|
}
|
|
894504
895060
|
filter.scope = scope;
|
|
@@ -894548,7 +895104,7 @@ async function handleRecallAdd(args2, context) {
|
|
|
894548
895104
|
const tags = tagsRaw ? tagsRaw.split(",").map((token) => token.trim()).filter(Boolean) : [];
|
|
894549
895105
|
const scope = scopeRaw && isValidScope(scopeRaw) ? scopeRaw : "project";
|
|
894550
895106
|
if (scopeRaw && !isValidScope(scopeRaw)) {
|
|
894551
|
-
context.print(`[memory] Invalid scope "${scopeRaw}". Valid values ${
|
|
895107
|
+
context.print(`[memory] Invalid scope "${scopeRaw}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
894552
895108
|
return;
|
|
894553
895109
|
}
|
|
894554
895110
|
const provenance = [];
|
|
@@ -894683,7 +895239,7 @@ function handleRecallExport(args2, context) {
|
|
|
894683
895239
|
if (scopeIdx !== -1 && commandArgs[scopeIdx + 1]) {
|
|
894684
895240
|
const scope = commandArgs[scopeIdx + 1];
|
|
894685
895241
|
if (!isValidScope(scope)) {
|
|
894686
|
-
context.print(`[memory] Unknown scope "${scope}". Valid values ${
|
|
895242
|
+
context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
894687
895243
|
return;
|
|
894688
895244
|
}
|
|
894689
895245
|
filter.scope = scope;
|
|
@@ -894762,7 +895318,7 @@ function handleRecallHandoffExport(args2, context) {
|
|
|
894762
895318
|
const scopeIdx = commandArgs.indexOf("--scope");
|
|
894763
895319
|
const scopeRaw = scopeIdx !== -1 ? commandArgs[scopeIdx + 1] : "team";
|
|
894764
895320
|
if (!scopeRaw || !isValidScope(scopeRaw)) {
|
|
894765
|
-
context.print(`[memory] Unknown scope "${scopeRaw ?? ""}". Valid values ${
|
|
895321
|
+
context.print(`[memory] Unknown scope "${scopeRaw ?? ""}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
894766
895322
|
return;
|
|
894767
895323
|
}
|
|
894768
895324
|
const bundle = memory.exportBundle({ scope: scopeRaw });
|
|
@@ -894878,7 +895434,7 @@ function handleRecallPromote(args2, context) {
|
|
|
894878
895434
|
const id = parsed.rest[0];
|
|
894879
895435
|
const scope = parsed.rest[1];
|
|
894880
895436
|
if (!id || !scope || !isValidScope(scope)) {
|
|
894881
|
-
context.print(`[memory] Usage: /memory promote <id> <${
|
|
895437
|
+
context.print(`[memory] Usage: /memory promote <id> <${VALID_SCOPES.join("|")}> --yes`);
|
|
894882
895438
|
return;
|
|
894883
895439
|
}
|
|
894884
895440
|
if (!parsed.yes) {
|
|
@@ -908468,7 +909024,7 @@ async function tryWireMemoryCommand(runtime2, normalized, rest) {
|
|
|
908468
909024
|
|
|
908469
909025
|
// src/cli/memory-command.ts
|
|
908470
909026
|
var VALID_CLASSES2 = ["decision", "constraint", "incident", "pattern", "fact", "risk", "runbook", "architecture", "ownership"];
|
|
908471
|
-
var
|
|
909027
|
+
var VALID_SCOPES3 = ["session", "project", "team"];
|
|
908472
909028
|
var VALID_REVIEW_STATES3 = ["fresh", "reviewed", "stale", "contradicted"];
|
|
908473
909029
|
var VALID_PROVENANCE_KINDS = ["session", "turn", "task", "event", "file"];
|
|
908474
909030
|
var VALUE_OPTIONS = new Set([
|
|
@@ -908568,7 +909124,7 @@ function isMemoryClass2(value) {
|
|
|
908568
909124
|
return VALID_CLASSES2.includes(value);
|
|
908569
909125
|
}
|
|
908570
909126
|
function isMemoryScope2(value) {
|
|
908571
|
-
return
|
|
909127
|
+
return VALID_SCOPES3.includes(value);
|
|
908572
909128
|
}
|
|
908573
909129
|
function isReviewState(value) {
|
|
908574
909130
|
return VALID_REVIEW_STATES3.includes(value);
|
|
@@ -908583,7 +909139,7 @@ function requireClass(value) {
|
|
|
908583
909139
|
}
|
|
908584
909140
|
function requireScope(value) {
|
|
908585
909141
|
if (!value || !isMemoryScope2(value))
|
|
908586
|
-
throw new Error(`Invalid memory scope "${value ?? ""}". Valid values ${
|
|
909142
|
+
throw new Error(`Invalid memory scope "${value ?? ""}". Valid values ${VALID_SCOPES3.join(", ")}`);
|
|
908587
909143
|
return value;
|
|
908588
909144
|
}
|
|
908589
909145
|
function optionalScope(value) {
|
|
@@ -923868,8 +924424,6 @@ function operatorContractMethods3() {
|
|
|
923868
924424
|
function operatorMethodSearchText(method) {
|
|
923869
924425
|
return [
|
|
923870
924426
|
method.id,
|
|
923871
|
-
method.title,
|
|
923872
|
-
method.description,
|
|
923873
924427
|
method.category,
|
|
923874
924428
|
method.http?.method,
|
|
923875
924429
|
method.http?.path,
|
|
@@ -974277,8 +974831,8 @@ function formatDigestTime(at, from = Date.now()) {
|
|
|
974277
974831
|
return `yesterday ${time4}`;
|
|
974278
974832
|
return `${d4.toLocaleDateString(undefined, { month: "short", day: "numeric" })} ${time4}`;
|
|
974279
974833
|
}
|
|
974280
|
-
function formatRelativeTime(targetMs,
|
|
974281
|
-
const diffMs = targetMs -
|
|
974834
|
+
function formatRelativeTime(targetMs, nowMs3 = Date.now()) {
|
|
974835
|
+
const diffMs = targetMs - nowMs3;
|
|
974282
974836
|
if (diffMs <= 0)
|
|
974283
974837
|
return "soon";
|
|
974284
974838
|
const diffMin = Math.round(diffMs / 60000);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-agent",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "GoodVibes personal operator assistant TUI with a proactive Agent product brain, isolated Agent Knowledge, local profiles, routines, skills, personas, and explicit build delegation.",
|
|
6
6
|
"type": "module",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
},
|
|
93
93
|
"dependencies": {},
|
|
94
94
|
"devDependencies": {
|
|
95
|
-
"@pellux/goodvibes-sdk": "1.
|
|
95
|
+
"@pellux/goodvibes-sdk": "1.4.0",
|
|
96
96
|
"sql.js": "^1.14.1",
|
|
97
97
|
"sqlite-vec": "^0.1.9",
|
|
98
98
|
"zustand": "^5.0.12",
|
|
@@ -88,10 +88,11 @@ function operatorContractMethods(): readonly OperatorContractMethod[] {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
function operatorMethodSearchText(method: OperatorContractMethod): string {
|
|
91
|
+
// EXCLUDES title/description prose: discovery keys off what a method IS
|
|
92
|
+
// (id/route/category/scopes), not how its docs read — SDK 1.4.0's "terminal
|
|
93
|
+
// turn.cancelled event" wording false-matched as a terminal/TTY capability.
|
|
91
94
|
return [
|
|
92
95
|
method.id,
|
|
93
|
-
method.title,
|
|
94
|
-
method.description,
|
|
95
96
|
method.category,
|
|
96
97
|
method.http?.method,
|
|
97
98
|
method.http?.path,
|
package/src/version.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { join } from 'node:path';
|
|
|
6
6
|
// The prebuild script updates the fallback value before compilation.
|
|
7
7
|
// Uses import.meta.dir (Bun) to locate package.json relative to this file,
|
|
8
8
|
// which is correct regardless of the process working directory.
|
|
9
|
-
let _version = '1.6.
|
|
9
|
+
let _version = '1.6.3';
|
|
10
10
|
try {
|
|
11
11
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8')) as {
|
|
12
12
|
readonly version?: unknown;
|