@ouro.bot/cli 0.1.0-alpha.47 → 0.1.0-alpha.49
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.json +16 -0
- package/dist/heart/bridges/manager.js +321 -0
- package/dist/heart/bridges/state-machine.js +115 -0
- package/dist/heart/bridges/store.js +123 -0
- package/dist/heart/daemon/thoughts.js +9 -1
- package/dist/heart/session-recall.js +116 -0
- package/dist/heart/turn-coordinator.js +28 -0
- package/dist/mind/pending.js +11 -0
- package/dist/mind/prompt.js +8 -1
- package/dist/repertoire/tasks/board.js +12 -0
- package/dist/repertoire/tasks/index.js +21 -0
- package/dist/repertoire/tools-base.js +136 -34
- package/dist/repertoire/tools.js +2 -0
- package/dist/senses/bluebubbles.js +127 -123
- package/dist/senses/cli.js +1 -0
- package/dist/senses/inner-dialog-worker.js +41 -15
- package/dist/senses/inner-dialog.js +1 -0
- package/dist/senses/pipeline.js +17 -0
- package/dist/senses/teams.js +1 -0
- package/package.json +1 -1
- package/subagents/work-doer.md +1 -1
- package/subagents/work-planner.md +1 -1
|
@@ -44,6 +44,7 @@ const path = __importStar(require("node:path"));
|
|
|
44
44
|
const core_1 = require("../heart/core");
|
|
45
45
|
const config_1 = require("../heart/config");
|
|
46
46
|
const identity_1 = require("../heart/identity");
|
|
47
|
+
const turn_coordinator_1 = require("../heart/turn-coordinator");
|
|
47
48
|
const context_1 = require("../mind/context");
|
|
48
49
|
const tokens_1 = require("../mind/friends/tokens");
|
|
49
50
|
const resolver_1 = require("../mind/friends/resolver");
|
|
@@ -547,143 +548,146 @@ async function handleBlueBubblesNormalizedEvent(event, resolvedDeps, source) {
|
|
|
547
548
|
},
|
|
548
549
|
});
|
|
549
550
|
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
(0,
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
551
|
+
return (0, turn_coordinator_1.withSharedTurnLock)("bluebubbles", sessPath, async () => {
|
|
552
|
+
// Pre-load session inside the turn lock so same-chat deliveries cannot race on stale trunk state.
|
|
553
|
+
const existing = resolvedDeps.loadSession(sessPath);
|
|
554
|
+
const sessionMessages = existing?.messages && existing.messages.length > 0
|
|
555
|
+
? existing.messages
|
|
556
|
+
: [{ role: "system", content: await resolvedDeps.buildSystem("bluebubbles", undefined, context) }];
|
|
557
|
+
if (event.kind === "message") {
|
|
558
|
+
const agentName = resolvedDeps.getAgentName();
|
|
559
|
+
if ((0, bluebubbles_inbound_log_1.hasRecordedBlueBubblesInbound)(agentName, event.chat.sessionKey, event.messageGuid)) {
|
|
560
|
+
(0, runtime_1.emitNervesEvent)({
|
|
561
|
+
component: "senses",
|
|
562
|
+
event: "senses.bluebubbles_recovery_skip",
|
|
563
|
+
message: "skipped bluebubbles message already recorded as handled",
|
|
564
|
+
meta: {
|
|
565
|
+
messageGuid: event.messageGuid,
|
|
566
|
+
sessionKey: event.chat.sessionKey,
|
|
567
|
+
source,
|
|
568
|
+
},
|
|
569
|
+
});
|
|
570
|
+
return { handled: true, notifiedAgent: false, kind: event.kind, reason: "already_processed" };
|
|
571
|
+
}
|
|
572
|
+
if (source !== "webhook" && sessionLikelyContainsMessage(event, existing?.messages ?? sessionMessages)) {
|
|
573
|
+
(0, bluebubbles_inbound_log_1.recordBlueBubblesInbound)(agentName, event, "recovery-bootstrap");
|
|
574
|
+
(0, runtime_1.emitNervesEvent)({
|
|
575
|
+
component: "senses",
|
|
576
|
+
event: "senses.bluebubbles_recovery_skip",
|
|
577
|
+
message: "skipped bluebubbles recovery because the session already contains the message text",
|
|
578
|
+
meta: {
|
|
579
|
+
messageGuid: event.messageGuid,
|
|
580
|
+
sessionKey: event.chat.sessionKey,
|
|
581
|
+
source,
|
|
582
|
+
},
|
|
583
|
+
});
|
|
584
|
+
return { handled: true, notifiedAgent: false, kind: event.kind, reason: "already_processed" };
|
|
585
|
+
}
|
|
569
586
|
}
|
|
570
|
-
|
|
571
|
-
|
|
587
|
+
// Build inbound user message (adapter concern: BB-specific content formatting)
|
|
588
|
+
const userMessage = {
|
|
589
|
+
role: "user",
|
|
590
|
+
content: buildInboundContent(event, existing?.messages ?? sessionMessages),
|
|
591
|
+
};
|
|
592
|
+
const callbacks = createBlueBubblesCallbacks(client, event.chat, replyTarget);
|
|
593
|
+
const controller = new AbortController();
|
|
594
|
+
// BB-specific tool context wrappers
|
|
595
|
+
const summarize = (0, core_1.createSummarize)();
|
|
596
|
+
const bbCapabilities = (0, channel_1.getChannelCapabilities)("bluebubbles");
|
|
597
|
+
const pendingDir = (0, pending_1.getPendingDir)(resolvedDeps.getAgentName(), friendId, "bluebubbles", event.chat.sessionKey);
|
|
598
|
+
// ── Compute trust gate context for group/acquaintance rules ─────
|
|
599
|
+
const groupHasFamilyMember = await checkGroupHasFamilyMember(store, event);
|
|
600
|
+
const hasExistingGroupWithFamily = event.chat.isGroup
|
|
601
|
+
? false
|
|
602
|
+
: await checkHasExistingGroupWithFamily(store, context.friend);
|
|
603
|
+
// ── Call shared pipeline ──────────────────────────────────────────
|
|
604
|
+
try {
|
|
605
|
+
const result = await (0, pipeline_1.handleInboundTurn)({
|
|
606
|
+
channel: "bluebubbles",
|
|
607
|
+
sessionKey: event.chat.sessionKey,
|
|
608
|
+
capabilities: bbCapabilities,
|
|
609
|
+
messages: [userMessage],
|
|
610
|
+
continuityIngressTexts: getBlueBubblesContinuityIngressTexts(event),
|
|
611
|
+
callbacks,
|
|
612
|
+
friendResolver: { resolve: () => Promise.resolve(context) },
|
|
613
|
+
sessionLoader: { loadOrCreate: () => Promise.resolve({ messages: sessionMessages, sessionPath: sessPath, state: existing?.state }) },
|
|
614
|
+
pendingDir,
|
|
615
|
+
friendStore: store,
|
|
616
|
+
provider: "imessage-handle",
|
|
617
|
+
externalId: event.sender.externalId || event.sender.rawId,
|
|
618
|
+
isGroupChat: event.chat.isGroup,
|
|
619
|
+
groupHasFamilyMember,
|
|
620
|
+
hasExistingGroupWithFamily,
|
|
621
|
+
enforceTrustGate: trust_gate_1.enforceTrustGate,
|
|
622
|
+
drainPending: pending_1.drainPending,
|
|
623
|
+
runAgent: (msgs, cb, channel, sig, opts) => resolvedDeps.runAgent(msgs, cb, channel, sig, {
|
|
624
|
+
...opts,
|
|
625
|
+
toolContext: {
|
|
626
|
+
/* v8 ignore next -- default no-op signin; pipeline provides the real one @preserve */
|
|
627
|
+
signin: async () => undefined,
|
|
628
|
+
...opts?.toolContext,
|
|
629
|
+
summarize,
|
|
630
|
+
bluebubblesReplyTarget: {
|
|
631
|
+
setSelection: (selection) => replyTarget.setSelection(selection),
|
|
632
|
+
},
|
|
633
|
+
codingFeedback: {
|
|
634
|
+
send: async (message) => {
|
|
635
|
+
await client.sendText({
|
|
636
|
+
chat: event.chat,
|
|
637
|
+
text: message,
|
|
638
|
+
replyToMessageGuid: replyTarget.getReplyToMessageGuid(),
|
|
639
|
+
});
|
|
640
|
+
},
|
|
641
|
+
},
|
|
642
|
+
},
|
|
643
|
+
}),
|
|
644
|
+
postTurn: resolvedDeps.postTurn,
|
|
645
|
+
accumulateFriendTokens: resolvedDeps.accumulateFriendTokens,
|
|
646
|
+
signal: controller.signal,
|
|
647
|
+
});
|
|
648
|
+
// ── Handle gate result ────────────────────────────────────────
|
|
649
|
+
if (!result.gateResult.allowed) {
|
|
650
|
+
// Send auto-reply via BB API if the gate provides one
|
|
651
|
+
if ("autoReply" in result.gateResult && result.gateResult.autoReply) {
|
|
652
|
+
await client.sendText({
|
|
653
|
+
chat: event.chat,
|
|
654
|
+
text: result.gateResult.autoReply,
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
if (event.kind === "message") {
|
|
658
|
+
(0, bluebubbles_inbound_log_1.recordBlueBubblesInbound)(resolvedDeps.getAgentName(), event, source);
|
|
659
|
+
}
|
|
660
|
+
return {
|
|
661
|
+
handled: true,
|
|
662
|
+
notifiedAgent: false,
|
|
663
|
+
kind: event.kind,
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
// Gate allowed — flush the agent's reply
|
|
667
|
+
await callbacks.flush();
|
|
668
|
+
if (event.kind === "message") {
|
|
669
|
+
(0, bluebubbles_inbound_log_1.recordBlueBubblesInbound)(resolvedDeps.getAgentName(), event, source);
|
|
670
|
+
}
|
|
572
671
|
(0, runtime_1.emitNervesEvent)({
|
|
573
672
|
component: "senses",
|
|
574
|
-
event: "senses.
|
|
575
|
-
message: "
|
|
673
|
+
event: "senses.bluebubbles_turn_end",
|
|
674
|
+
message: "bluebubbles event handled",
|
|
576
675
|
meta: {
|
|
577
676
|
messageGuid: event.messageGuid,
|
|
677
|
+
kind: event.kind,
|
|
578
678
|
sessionKey: event.chat.sessionKey,
|
|
579
|
-
source,
|
|
580
679
|
},
|
|
581
680
|
});
|
|
582
|
-
return { handled: true, notifiedAgent: false, kind: event.kind, reason: "already_processed" };
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
// Build inbound user message (adapter concern: BB-specific content formatting)
|
|
586
|
-
const userMessage = {
|
|
587
|
-
role: "user",
|
|
588
|
-
content: buildInboundContent(event, existing?.messages ?? sessionMessages),
|
|
589
|
-
};
|
|
590
|
-
const callbacks = createBlueBubblesCallbacks(client, event.chat, replyTarget);
|
|
591
|
-
const controller = new AbortController();
|
|
592
|
-
// BB-specific tool context wrappers
|
|
593
|
-
const summarize = (0, core_1.createSummarize)();
|
|
594
|
-
const bbCapabilities = (0, channel_1.getChannelCapabilities)("bluebubbles");
|
|
595
|
-
const pendingDir = (0, pending_1.getPendingDir)(resolvedDeps.getAgentName(), friendId, "bluebubbles", event.chat.sessionKey);
|
|
596
|
-
// ── Compute trust gate context for group/acquaintance rules ─────
|
|
597
|
-
const groupHasFamilyMember = await checkGroupHasFamilyMember(store, event);
|
|
598
|
-
const hasExistingGroupWithFamily = event.chat.isGroup
|
|
599
|
-
? false
|
|
600
|
-
: await checkHasExistingGroupWithFamily(store, context.friend);
|
|
601
|
-
// ── Call shared pipeline ──────────────────────────────────────────
|
|
602
|
-
try {
|
|
603
|
-
const result = await (0, pipeline_1.handleInboundTurn)({
|
|
604
|
-
channel: "bluebubbles",
|
|
605
|
-
capabilities: bbCapabilities,
|
|
606
|
-
messages: [userMessage],
|
|
607
|
-
continuityIngressTexts: getBlueBubblesContinuityIngressTexts(event),
|
|
608
|
-
callbacks,
|
|
609
|
-
friendResolver: { resolve: () => Promise.resolve(context) },
|
|
610
|
-
sessionLoader: { loadOrCreate: () => Promise.resolve({ messages: sessionMessages, sessionPath: sessPath, state: existing?.state }) },
|
|
611
|
-
pendingDir,
|
|
612
|
-
friendStore: store,
|
|
613
|
-
provider: "imessage-handle",
|
|
614
|
-
externalId: event.sender.externalId || event.sender.rawId,
|
|
615
|
-
isGroupChat: event.chat.isGroup,
|
|
616
|
-
groupHasFamilyMember,
|
|
617
|
-
hasExistingGroupWithFamily,
|
|
618
|
-
enforceTrustGate: trust_gate_1.enforceTrustGate,
|
|
619
|
-
drainPending: pending_1.drainPending,
|
|
620
|
-
runAgent: (msgs, cb, channel, sig, opts) => resolvedDeps.runAgent(msgs, cb, channel, sig, {
|
|
621
|
-
...opts,
|
|
622
|
-
toolContext: {
|
|
623
|
-
/* v8 ignore next -- default no-op signin; pipeline provides the real one @preserve */
|
|
624
|
-
signin: async () => undefined,
|
|
625
|
-
...opts?.toolContext,
|
|
626
|
-
summarize,
|
|
627
|
-
bluebubblesReplyTarget: {
|
|
628
|
-
setSelection: (selection) => replyTarget.setSelection(selection),
|
|
629
|
-
},
|
|
630
|
-
codingFeedback: {
|
|
631
|
-
send: async (message) => {
|
|
632
|
-
await client.sendText({
|
|
633
|
-
chat: event.chat,
|
|
634
|
-
text: message,
|
|
635
|
-
replyToMessageGuid: replyTarget.getReplyToMessageGuid(),
|
|
636
|
-
});
|
|
637
|
-
},
|
|
638
|
-
},
|
|
639
|
-
},
|
|
640
|
-
}),
|
|
641
|
-
postTurn: resolvedDeps.postTurn,
|
|
642
|
-
accumulateFriendTokens: resolvedDeps.accumulateFriendTokens,
|
|
643
|
-
signal: controller.signal,
|
|
644
|
-
});
|
|
645
|
-
// ── Handle gate result ────────────────────────────────────────
|
|
646
|
-
if (!result.gateResult.allowed) {
|
|
647
|
-
// Send auto-reply via BB API if the gate provides one
|
|
648
|
-
if ("autoReply" in result.gateResult && result.gateResult.autoReply) {
|
|
649
|
-
await client.sendText({
|
|
650
|
-
chat: event.chat,
|
|
651
|
-
text: result.gateResult.autoReply,
|
|
652
|
-
});
|
|
653
|
-
}
|
|
654
|
-
if (event.kind === "message") {
|
|
655
|
-
(0, bluebubbles_inbound_log_1.recordBlueBubblesInbound)(resolvedDeps.getAgentName(), event, source);
|
|
656
|
-
}
|
|
657
681
|
return {
|
|
658
682
|
handled: true,
|
|
659
|
-
notifiedAgent:
|
|
683
|
+
notifiedAgent: true,
|
|
660
684
|
kind: event.kind,
|
|
661
685
|
};
|
|
662
686
|
}
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
if (event.kind === "message") {
|
|
666
|
-
(0, bluebubbles_inbound_log_1.recordBlueBubblesInbound)(resolvedDeps.getAgentName(), event, source);
|
|
687
|
+
finally {
|
|
688
|
+
await callbacks.finish();
|
|
667
689
|
}
|
|
668
|
-
|
|
669
|
-
component: "senses",
|
|
670
|
-
event: "senses.bluebubbles_turn_end",
|
|
671
|
-
message: "bluebubbles event handled",
|
|
672
|
-
meta: {
|
|
673
|
-
messageGuid: event.messageGuid,
|
|
674
|
-
kind: event.kind,
|
|
675
|
-
sessionKey: event.chat.sessionKey,
|
|
676
|
-
},
|
|
677
|
-
});
|
|
678
|
-
return {
|
|
679
|
-
handled: true,
|
|
680
|
-
notifiedAgent: true,
|
|
681
|
-
kind: event.kind,
|
|
682
|
-
};
|
|
683
|
-
}
|
|
684
|
-
finally {
|
|
685
|
-
await callbacks.finish();
|
|
686
|
-
}
|
|
690
|
+
});
|
|
687
691
|
}
|
|
688
692
|
async function handleBlueBubblesEvent(payload, deps = {}) {
|
|
689
693
|
const resolvedDeps = { ...defaultDeps, ...deps };
|
package/dist/senses/cli.js
CHANGED
|
@@ -752,6 +752,7 @@ async function main(agentName, options) {
|
|
|
752
752
|
// User message passed via input.messages so the pipeline can prepend pending messages to it.
|
|
753
753
|
const result = await (0, pipeline_1.handleInboundTurn)({
|
|
754
754
|
channel: "cli",
|
|
755
|
+
sessionKey: "session",
|
|
755
756
|
capabilities: cliCapabilities,
|
|
756
757
|
messages: [{ role: "user", content: userInput }],
|
|
757
758
|
continuityIngressTexts: getCliContinuityIngressTexts(userInput),
|
|
@@ -4,26 +4,52 @@ exports.createInnerDialogWorker = createInnerDialogWorker;
|
|
|
4
4
|
exports.startInnerDialogWorker = startInnerDialogWorker;
|
|
5
5
|
const inner_dialog_1 = require("./inner-dialog");
|
|
6
6
|
const runtime_1 = require("../nerves/runtime");
|
|
7
|
-
|
|
7
|
+
const identity_1 = require("../heart/identity");
|
|
8
|
+
const pending_1 = require("../mind/pending");
|
|
9
|
+
function createInnerDialogWorker(runTurn = (options) => (0, inner_dialog_1.runInnerDialogTurn)(options), hasPendingWork = () => (0, pending_1.hasPendingMessages)((0, pending_1.getInnerDialogPendingDir)((0, identity_1.getAgentName)()))) {
|
|
8
10
|
let running = false;
|
|
11
|
+
let rerunRequested = false;
|
|
12
|
+
let rerunReason = "instinct";
|
|
13
|
+
let rerunTaskId;
|
|
9
14
|
async function run(reason, taskId) {
|
|
10
|
-
if (running)
|
|
15
|
+
if (running) {
|
|
16
|
+
rerunRequested = true;
|
|
17
|
+
rerunReason = reason;
|
|
18
|
+
if (taskId !== undefined) {
|
|
19
|
+
rerunTaskId = taskId;
|
|
20
|
+
}
|
|
11
21
|
return;
|
|
22
|
+
}
|
|
12
23
|
running = true;
|
|
13
24
|
try {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
let nextReason = reason;
|
|
26
|
+
let nextTaskId = taskId;
|
|
27
|
+
do {
|
|
28
|
+
rerunRequested = false;
|
|
29
|
+
try {
|
|
30
|
+
await runTurn({ reason: nextReason, taskId: nextTaskId });
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
(0, runtime_1.emitNervesEvent)({
|
|
34
|
+
level: "error",
|
|
35
|
+
component: "senses",
|
|
36
|
+
event: "senses.inner_dialog_worker_error",
|
|
37
|
+
message: "inner dialog worker turn failed",
|
|
38
|
+
meta: {
|
|
39
|
+
reason: nextReason,
|
|
40
|
+
error: error instanceof Error ? error.message : String(error),
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (!rerunRequested && hasPendingWork()) {
|
|
45
|
+
rerunRequested = true;
|
|
46
|
+
rerunReason = "instinct";
|
|
47
|
+
}
|
|
48
|
+
nextReason = rerunReason;
|
|
49
|
+
nextTaskId = rerunTaskId;
|
|
50
|
+
rerunReason = "instinct";
|
|
51
|
+
rerunTaskId = undefined;
|
|
52
|
+
} while (rerunRequested);
|
|
27
53
|
}
|
|
28
54
|
finally {
|
|
29
55
|
running = false;
|
|
@@ -337,6 +337,7 @@ async function runInnerDialogTurn(options) {
|
|
|
337
337
|
const traceId = (0, nerves_1.createTraceId)();
|
|
338
338
|
const result = await (0, pipeline_1.handleInboundTurn)({
|
|
339
339
|
channel: "inner",
|
|
340
|
+
sessionKey: "dialog",
|
|
340
341
|
capabilities: innerCapabilities,
|
|
341
342
|
messages: [userMessage],
|
|
342
343
|
continuityIngressTexts: [],
|
package/dist/senses/pipeline.js
CHANGED
|
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
8
8
|
exports.handleInboundTurn = handleInboundTurn;
|
|
9
9
|
const runtime_1 = require("../nerves/runtime");
|
|
10
10
|
const continuity_1 = require("./continuity");
|
|
11
|
+
const manager_1 = require("../heart/bridges/manager");
|
|
11
12
|
// ── Pipeline ──────────────────────────────────────────────────────
|
|
12
13
|
async function handleInboundTurn(input) {
|
|
13
14
|
// Step 1: Resolve friend
|
|
@@ -60,6 +61,18 @@ async function handleInboundTurn(input) {
|
|
|
60
61
|
?.map((text) => text.trim())
|
|
61
62
|
.filter((text) => text.length > 0)
|
|
62
63
|
.at(-1);
|
|
64
|
+
const currentSession = {
|
|
65
|
+
friendId: resolvedContext.friend.id,
|
|
66
|
+
channel: input.channel,
|
|
67
|
+
key: input.sessionKey ?? "session",
|
|
68
|
+
sessionPath: session.sessionPath,
|
|
69
|
+
};
|
|
70
|
+
const activeBridges = (0, manager_1.createBridgeManager)().findBridgesForSession({
|
|
71
|
+
friendId: currentSession.friendId,
|
|
72
|
+
channel: currentSession.channel,
|
|
73
|
+
key: currentSession.key,
|
|
74
|
+
});
|
|
75
|
+
const bridgeContext = (0, manager_1.formatBridgeContext)(activeBridges) || undefined;
|
|
63
76
|
// Step 4: Drain pending messages
|
|
64
77
|
const pending = input.drainPending(input.pendingDir);
|
|
65
78
|
// Assemble messages: session messages + pending (formatted) + inbound user messages
|
|
@@ -98,6 +111,8 @@ async function handleInboundTurn(input) {
|
|
|
98
111
|
const existingToolContext = input.runAgentOptions?.toolContext;
|
|
99
112
|
const runAgentOptions = {
|
|
100
113
|
...input.runAgentOptions,
|
|
114
|
+
bridgeContext,
|
|
115
|
+
currentSessionKey: currentSession.key,
|
|
101
116
|
currentObligation,
|
|
102
117
|
mustResolveBeforeHandoff,
|
|
103
118
|
setMustResolveBeforeHandoff: (value) => {
|
|
@@ -109,6 +124,8 @@ async function handleInboundTurn(input) {
|
|
|
109
124
|
...existingToolContext,
|
|
110
125
|
context: resolvedContext,
|
|
111
126
|
friendStore: input.friendStore,
|
|
127
|
+
currentSession,
|
|
128
|
+
activeBridges,
|
|
112
129
|
},
|
|
113
130
|
};
|
|
114
131
|
const result = await input.runAgent(sessionMessages, input.callbacks, input.channel, input.signal, runAgentOptions);
|
package/dist/senses/teams.js
CHANGED
|
@@ -534,6 +534,7 @@ async function handleTeamsMessage(text, stream, conversationId, teamsContext, se
|
|
|
534
534
|
// ── Call shared pipeline ──────────────────────────────────────────
|
|
535
535
|
const result = await (0, pipeline_1.handleInboundTurn)({
|
|
536
536
|
channel: "teams",
|
|
537
|
+
sessionKey: conversationId,
|
|
537
538
|
capabilities: teamsCapabilities,
|
|
538
539
|
messages: [{ role: "user", content: currentText }],
|
|
539
540
|
continuityIngressTexts: [currentText],
|
package/package.json
CHANGED
package/subagents/work-doer.md
CHANGED
|
@@ -9,7 +9,7 @@ You are a task executor. Read a doing.md file and execute all units sequentially
|
|
|
9
9
|
## On Startup
|
|
10
10
|
|
|
11
11
|
1. **Find task-doc directory**: Read project instructions (for example `AGENTS.md`) to determine where planning/doing docs live for this repo
|
|
12
|
-
2. **Confirm worktree**: Run from the dedicated task worktree required by the project. If the current checkout is shared, ambiguous, or not on the task branch,
|
|
12
|
+
2. **Confirm worktree**: Run from the dedicated task worktree required by the project. If the current checkout is shared, ambiguous, or not on the task branch, switch/create the correct worktree first when project instructions allow it. Only STOP to ask the user when they explicitly want to control naming/layout or automatic creation fails.
|
|
13
13
|
3. **Find doing doc**: Look for `YYYY-MM-DD-HHMM-doing-*.md` in that project-defined task-doc directory
|
|
14
14
|
4. If multiple found, ask which one
|
|
15
15
|
5. If none found, ask user for location
|
|
@@ -11,7 +11,7 @@ You are a task planner for coding work. Help the user define scope, then convert
|
|
|
11
11
|
**Determine task doc directory:**
|
|
12
12
|
1. Read project instructions (for example `AGENTS.md`) to find the canonical task-doc location for the current repo
|
|
13
13
|
2. Derive `AGENT` from the current git branch when the project uses agent-scoped task docs
|
|
14
|
-
3. Confirm the task is running from a dedicated task worktree when the project requires parallel agent work; if the checkout is shared or ambiguous,
|
|
14
|
+
3. Confirm the task is running from a dedicated task worktree when the project requires parallel agent work; if the checkout is shared or ambiguous, create/switch to the dedicated worktree yourself when project instructions allow it, and only STOP to ask the caller when they explicitly want to control naming/layout or automatic creation fails
|
|
15
15
|
4. Set `TASK_DIR` to the project-defined planning/doing directory
|
|
16
16
|
5. If the project-defined parent location exists but `TASK_DIR` does not, create it
|
|
17
17
|
6. If the project does not define a task-doc location, STOP and ask the user or caller where planning/doing docs should live
|