toolroll 0.9.55 → 0.9.57
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 +18 -0
- package/README.md +24 -8
- package/dist/action-ledger.d.ts +2 -4
- package/dist/action-ledger.js +2 -10
- package/dist/approval-policy.d.ts +5 -5
- package/dist/approval-policy.js +4 -4
- package/dist/approval-rules-ui.js +2 -2
- package/dist/assignment-adapters.d.ts +5 -0
- package/dist/assignment.d.ts +24 -3
- package/dist/assignment.js +36 -10
- package/dist/browser/workspace.js +5 -5
- package/dist/browser-workspace.d.ts +12 -12
- package/dist/browser-workspace.js +1 -1
- package/dist/budget-alerts.js +3 -3
- package/dist/chat-actions.d.ts +23 -18
- package/dist/chat-actions.js +110 -88
- package/dist/chat-ask.d.ts +2 -2
- package/dist/chat-ask.js +5 -5
- package/dist/chat-channel.d.ts +15 -15
- package/dist/chat-channel.js +20 -20
- package/dist/chat-controls.d.ts +0 -4
- package/dist/chat-controls.js +0 -1
- package/dist/chat-core.js +1 -1
- package/dist/chat-delivery-state.js +2 -2
- package/dist/chat-delivery.d.ts +2 -2
- package/dist/chat-delivery.js +30 -37
- package/dist/chat-flow.js +3 -3
- package/dist/chat-messages.d.ts +1 -1
- package/dist/chat-messages.js +4 -4
- package/dist/chat-migration.d.ts +1 -1
- package/dist/chat-migration.js +11 -11
- package/dist/chat-rooms.js +3 -3
- package/dist/chat-voice.js +1 -1
- package/dist/chat-warmth.d.ts +2 -2
- package/dist/check-levels.d.ts +3 -0
- package/dist/check-levels.js +5 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +6 -7
- package/dist/contracts/chat-actions.d.ts +32 -27
- package/dist/contracts/chat-actions.js +29 -11
- package/dist/contracts/chat-content.d.ts +1 -1
- package/dist/contracts/chat-content.js +1 -1
- package/dist/contracts/chat-tables.js +4 -4
- package/dist/contracts/console-api.d.ts +6 -6
- package/dist/contracts/console-api.js +7 -7
- package/dist/contracts/flow-propose.d.ts +3 -3
- package/dist/contracts/flow.d.ts +132 -125
- package/dist/contracts/flow.js +27 -12
- package/dist/contracts/lead-context.d.ts +1 -1
- package/dist/contracts/lead-context.js +2 -2
- package/dist/contracts/lead-tools.d.ts +20 -18
- package/dist/contracts/lead-tools.js +15 -15
- package/dist/contracts/stage-output.d.ts +1 -1
- package/dist/contracts/stage-output.js +1 -1
- package/dist/contracts/store-json.d.ts +23 -22
- package/dist/contracts/store-json.js +17 -17
- package/dist/contracts/{teammate-turn.d.ts → subagent-turn.d.ts} +5 -5
- package/dist/contracts/{teammate-turn.js → subagent-turn.js} +7 -7
- package/dist/converse.d.ts +23 -23
- package/dist/converse.js +28 -28
- package/dist/coordinator-proposals.d.ts +2 -2
- package/dist/coordinator-proposals.js +1 -1
- package/dist/coordinator.js +1 -1
- package/dist/deprecations.d.ts +12 -0
- package/dist/deprecations.js +20 -0
- package/dist/desktop-update-gate.js +8 -4
- package/dist/desktop-update.js +6 -1
- package/dist/discord-chat.js +6 -6
- package/dist/dispatch.d.ts +1 -1
- package/dist/dispatch.js +1 -1
- package/dist/dispose.js +0 -5
- package/dist/envelope.js +0 -1
- package/dist/export-ui.js +1 -1
- package/dist/export.js +7 -7
- package/dist/flow-engine.d.ts +2 -2
- package/dist/flow-engine.js +21 -21
- package/dist/flow-insights.d.ts +1 -1
- package/dist/flow-share.js +13 -8
- package/dist/flow-steps.d.ts +5 -5
- package/dist/flow-steps.js +19 -19
- package/dist/flow-triggers.d.ts +1 -1
- package/dist/flow-triggers.js +1 -1
- package/dist/flows-cli.js +1 -1
- package/dist/flows-ui.js +20 -20
- package/dist/flows.js +19 -19
- package/dist/guides.js +4 -3
- package/dist/invoke.js +1 -1
- package/dist/kits-ui.js +5 -5
- package/dist/kits.d.ts +12 -12
- package/dist/kits.js +31 -31
- package/dist/{mate-cli.d.ts → lead-cli.d.ts} +11 -11
- package/dist/{mate-cli.js → lead-cli.js} +38 -38
- package/dist/lead-commitments.js +4 -4
- package/dist/lead-context.d.ts +2 -2
- package/dist/lead-context.js +9 -9
- package/dist/{mate-contract.d.ts → lead-contract.d.ts} +3 -3
- package/dist/{mate-contract.js → lead-contract.js} +7 -6
- package/dist/{mate-doors.d.ts → lead-doors.d.ts} +6 -6
- package/dist/{mate-doors.js → lead-doors.js} +24 -24
- package/dist/lead-follow.d.ts +5 -5
- package/dist/lead-follow.js +9 -9
- package/dist/lead-people.d.ts +5 -5
- package/dist/lead-people.js +14 -14
- package/dist/{mate-progress.d.ts → lead-progress.d.ts} +9 -9
- package/dist/{mate-progress.js → lead-progress.js} +3 -3
- package/dist/lead-status.d.ts +1 -1
- package/dist/lead-status.js +2 -2
- package/dist/{mate-tools.d.ts → lead-tools.d.ts} +19 -19
- package/dist/{mate-tools.js → lead-tools.js} +109 -101
- package/dist/{mate.d.ts → lead.d.ts} +27 -27
- package/dist/{mate.js → lead.js} +102 -102
- package/dist/limits-ui.d.ts +1 -1
- package/dist/limits-ui.js +1 -1
- package/dist/mcp-connect.d.ts +1 -1
- package/dist/mcp-connect.js +3 -3
- package/dist/mcp-core.js +1 -1
- package/dist/memory-pass.d.ts +2 -2
- package/dist/memory-pass.js +7 -7
- package/dist/notification-rows.d.ts +2 -2
- package/dist/operate.d.ts +3 -3
- package/dist/operate.js +52 -42
- package/dist/policy.d.ts +1 -1
- package/dist/principal.d.ts +1 -1
- package/dist/principal.js +2 -2
- package/dist/project-delete-ui.js +1 -1
- package/dist/project-delete.d.ts +1 -1
- package/dist/project-delete.js +26 -26
- package/dist/project-memory.js +1 -1
- package/dist/project-tools.d.ts +1 -1
- package/dist/project-tools.js +1 -1
- package/dist/proof.d.ts +9 -0
- package/dist/proof.js +12 -0
- package/dist/recipe-ui.js +1 -1
- package/dist/release-coverage.d.ts +16 -0
- package/dist/release-coverage.js +92 -0
- package/dist/retention.js +4 -4
- package/dist/scope.d.ts +2 -2
- package/dist/scout-report.d.ts +1 -1
- package/dist/scout-report.js +1 -1
- package/dist/serve.js +40 -45
- package/dist/server/chat.d.ts +4 -4
- package/dist/server/chat.js +105 -103
- package/dist/server/chrome.js +3 -3
- package/dist/server/flows.js +69 -62
- package/dist/server/guards.js +3 -3
- package/dist/server/http.d.ts +3 -3
- package/dist/server/http.js +1 -1
- package/dist/server/live.js +6 -6
- package/dist/server/people-tokens.js +1 -1
- package/dist/server/remote.js +12 -10
- package/dist/server/render-chat.d.ts +30 -30
- package/dist/server/render-chat.js +33 -33
- package/dist/server/render-pages.js +2 -2
- package/dist/server/render-results.d.ts +4 -1
- package/dist/server/render-results.js +23 -9
- package/dist/server/render-settings.d.ts +7 -0
- package/dist/server/render-settings.js +3 -0
- package/dist/server/route-table.js +9 -7
- package/dist/server/runtime.d.ts +13 -13
- package/dist/server/settings.js +14 -13
- package/dist/server/tasks.js +34 -30
- package/dist/setup-guide.d.ts +2 -2
- package/dist/slack-chat.d.ts +2 -2
- package/dist/slack-chat.js +6 -6
- package/dist/spend-ui.d.ts +3 -3
- package/dist/spend-ui.js +9 -9
- package/dist/spend.d.ts +14 -14
- package/dist/spend.js +31 -31
- package/dist/store-baseline.d.ts +19 -0
- package/dist/store-baseline.js +2873 -0
- package/dist/store.d.ts +200 -254
- package/dist/store.js +830 -3152
- package/dist/subagent-admin.d.ts +53 -0
- package/dist/{teammate-admin.js → subagent-admin.js} +37 -37
- package/dist/{teammate-desk.d.ts → subagent-desk.d.ts} +22 -23
- package/dist/{teammate-desk.js → subagent-desk.js} +26 -35
- package/dist/{teammate-memory.d.ts → subagent-memory.d.ts} +17 -17
- package/dist/{teammate-memory.js → subagent-memory.js} +41 -41
- package/dist/{teammate-question.d.ts → subagent-question.d.ts} +6 -6
- package/dist/{teammate-question.js → subagent-question.js} +17 -17
- package/dist/{teammate-tools.d.ts → subagent-tools.d.ts} +18 -18
- package/dist/{teammate-tools.js → subagent-tools.js} +36 -36
- package/dist/{teammate-week.d.ts → subagent-week.d.ts} +10 -10
- package/dist/{teammate-week.js → subagent-week.js} +23 -23
- package/dist/{teammate-work.d.ts → subagent-work.d.ts} +21 -21
- package/dist/{teammate-work.js → subagent-work.js} +50 -50
- package/dist/subagents-ui.d.ts +22 -0
- package/dist/{teammates-ui.js → subagents-ui.js} +45 -45
- package/dist/{teammates.d.ts → subagents.d.ts} +11 -11
- package/dist/{teammates.js → subagents.js} +21 -21
- package/dist/subscription-chat.d.ts +13 -13
- package/dist/subscription-chat.js +19 -19
- package/dist/surface.d.ts +19 -2
- package/dist/surface.js +7 -31
- package/dist/task-outcome-cli.js +3 -1
- package/dist/task-status.d.ts +59 -7
- package/dist/task-status.js +132 -16
- package/dist/team-cli.d.ts +1 -0
- package/dist/team-cli.js +14 -2
- package/dist/team-leads.js +13 -13
- package/dist/team-runtime.d.ts +2 -2
- package/dist/team-runtime.js +9 -9
- package/dist/teams-chat.js +6 -6
- package/dist/telegram-flow.d.ts +3 -3
- package/dist/telegram-flow.js +3 -3
- package/dist/{telegram-mate.d.ts → telegram-lead.d.ts} +5 -5
- package/dist/{telegram-mate.js → telegram-lead.js} +27 -27
- package/dist/telegram-status.d.ts +11 -4
- package/dist/telegram-status.js +18 -11
- package/dist/telegram-team.d.ts +1 -1
- package/dist/telegram-team.js +5 -5
- package/dist/telegram.d.ts +1 -1
- package/dist/telegram.js +13 -34
- package/dist/text-limits.d.ts +18 -18
- package/dist/text-limits.js +18 -18
- package/dist/toolroll-update.d.ts +8 -0
- package/dist/toolroll-update.js +45 -8
- package/dist/work-index.d.ts +6 -1
- package/dist/work-index.js +50 -8
- package/dist/workspace-ui.js +2 -1
- package/package.json +1 -2
- package/dist/teammate-admin.d.ts +0 -53
- package/dist/teammates-ui.d.ts +0 -21
|
@@ -765,7 +765,7 @@ export type BrowserRunChecks = {
|
|
|
765
765
|
export type BrowserFlowStage = {
|
|
766
766
|
id: string;
|
|
767
767
|
title: string;
|
|
768
|
-
kind: "inbox" | "task" | "report" | "approval" | "check" | "pull-request" | "update" | "notify" | "sort" | "draft" | "request" | "email" | "tool" | "wait" | "
|
|
768
|
+
kind: "inbox" | "task" | "report" | "approval" | "check" | "pull-request" | "update" | "notify" | "sort" | "draft" | "request" | "email" | "tool" | "wait" | "subagent" | "send" | "choose" | "done";
|
|
769
769
|
zone: {
|
|
770
770
|
x: number;
|
|
771
771
|
y: number;
|
|
@@ -835,9 +835,9 @@ export type BrowserFlowStage = {
|
|
|
835
835
|
minutes: number;
|
|
836
836
|
to: string | null;
|
|
837
837
|
} | undefined;
|
|
838
|
-
/** v92: the
|
|
839
|
-
|
|
840
|
-
/** v96: a
|
|
838
|
+
/** v92: the subagent who decides (an approval zone) or handles (a subagent zone) it. */
|
|
839
|
+
subagent?: string | undefined;
|
|
840
|
+
/** v96: a subagent zone sends what the subagent writes back to whoever asked. */
|
|
841
841
|
reply?: boolean | undefined;
|
|
842
842
|
/** A "Person chooses" zone's buttons: each one's words and the zone it leads to ("end" ignores the card). */
|
|
843
843
|
options?: {
|
|
@@ -921,7 +921,7 @@ export type BrowserFlowCard = {
|
|
|
921
921
|
at: string;
|
|
922
922
|
label: string;
|
|
923
923
|
} | null;
|
|
924
|
-
/** v92: a
|
|
924
|
+
/** v92: a subagent's open question about this visit, and whether the viewer is the one asked. */
|
|
925
925
|
question?: {
|
|
926
926
|
id: number;
|
|
927
927
|
from: string;
|
|
@@ -932,13 +932,13 @@ export type BrowserFlowCard = {
|
|
|
932
932
|
}[];
|
|
933
933
|
askedOf: string;
|
|
934
934
|
mine: boolean;
|
|
935
|
-
/** v94: a tool call waiting for approval — why the
|
|
935
|
+
/** v94: a tool call waiting for approval — why the subagent wants it, and why it needs approval. */
|
|
936
936
|
call?: {
|
|
937
937
|
why: string;
|
|
938
938
|
rule: string;
|
|
939
939
|
} | null;
|
|
940
940
|
} | null;
|
|
941
|
-
/** v92: what the
|
|
941
|
+
/** v92: what the subagent said when it handed this decision to a person. */
|
|
942
942
|
handoff?: {
|
|
943
943
|
from: string;
|
|
944
944
|
note: string;
|
|
@@ -973,7 +973,7 @@ export type BrowserFlowCard = {
|
|
|
973
973
|
person: string;
|
|
974
974
|
at: string;
|
|
975
975
|
} | null;
|
|
976
|
-
/** v94: every tool call
|
|
976
|
+
/** v94: every tool call subagents made or asked to make on this card, oldest first: the receipts. */
|
|
977
977
|
calls?: {
|
|
978
978
|
id: number;
|
|
979
979
|
who: string;
|
|
@@ -983,8 +983,8 @@ export type BrowserFlowCard = {
|
|
|
983
983
|
why: string;
|
|
984
984
|
result: string | null;
|
|
985
985
|
at: string;
|
|
986
|
-
/** v97: the
|
|
987
|
-
|
|
986
|
+
/** v97: the subagent's id and the action that undoes this call, when a person can press Undo. */
|
|
987
|
+
subagent?: number;
|
|
988
988
|
undo?: string | null;
|
|
989
989
|
}[];
|
|
990
990
|
};
|
|
@@ -1065,8 +1065,8 @@ export type BrowserFlowView = {
|
|
|
1065
1065
|
me: string;
|
|
1066
1066
|
/** Whether sort zones can run: an OpenRouter key is saved in Settings → AI providers. */
|
|
1067
1067
|
sortReady: boolean;
|
|
1068
|
-
/** v92: the project's
|
|
1069
|
-
|
|
1068
|
+
/** v92: the project's subagents, to staff zones with. */
|
|
1069
|
+
subagents?: {
|
|
1070
1070
|
handle: string;
|
|
1071
1071
|
label: string;
|
|
1072
1072
|
name: string;
|
|
@@ -19,7 +19,7 @@ export function browserCrewOf(store, now, access, options = {}) {
|
|
|
19
19
|
return { crew: [], crewTruncated: false };
|
|
20
20
|
const limit = Number.isFinite(options.limit)
|
|
21
21
|
? Math.max(1, Math.min(BROWSER_CREW_LIMIT, Math.floor(options.limit))) : BROWSER_CREW_LIMIT;
|
|
22
|
-
const page = workIndexPage(store, now, access, { limit, project });
|
|
22
|
+
const page = workIndexPage(store, now, access, { limit, project, ...(options.evidenceRoot === undefined ? {} : { root: options.evidenceRoot }) });
|
|
23
23
|
return browserCrewFromIndex(page);
|
|
24
24
|
}
|
|
25
25
|
/** Navigation input must already be admitted by the caller. No extra project
|
package/dist/budget-alerts.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { budgetLabel,
|
|
1
|
+
import { budgetLabel, subagentNames, usd } from "./spend.js";
|
|
2
2
|
const MARKS = [100, 80, 50];
|
|
3
3
|
export function budgetAlertPass(store, now) {
|
|
4
4
|
const { month, budgets } = store.monthSpend(now);
|
|
5
5
|
const sent = [];
|
|
6
|
-
const names =
|
|
6
|
+
const names = subagentNames(store.handle);
|
|
7
7
|
for (const budget of budgets) {
|
|
8
8
|
const mark = MARKS.find(one => budget.percent >= one);
|
|
9
9
|
if (mark === undefined)
|
|
@@ -13,7 +13,7 @@ export function budgetAlertPass(store, now) {
|
|
|
13
13
|
// A higher mark already sent this month covers this one.
|
|
14
14
|
if (MARKS.filter(one => one >= mark).some(one => store.handle.prepare("SELECT 1 AS hit FROM notification WHERE dedupe_key = ?").get(key(one)) !== undefined))
|
|
15
15
|
continue;
|
|
16
|
-
const label = budgetLabel(budget, budget.scope === "
|
|
16
|
+
const label = budgetLabel(budget, budget.scope === "subagent" ? names.get(Number(budget.key)) : undefined);
|
|
17
17
|
const fresh = store.enqueueNotification({
|
|
18
18
|
dedupeKey: key(mark), kind: "budget-alert", pushClass: "attention", link: `/spend?month=${month}`,
|
|
19
19
|
subject: `${label} budget: ${mark}% used`,
|
package/dist/chat-actions.d.ts
CHANGED
|
@@ -143,48 +143,53 @@ export declare const CHAT_ACTIONS: {
|
|
|
143
143
|
readonly protected: false;
|
|
144
144
|
readonly password: false;
|
|
145
145
|
};
|
|
146
|
-
readonly
|
|
147
|
-
readonly label: "Add
|
|
146
|
+
readonly subagent_create: {
|
|
147
|
+
readonly label: "Add subagent";
|
|
148
148
|
readonly protected: false;
|
|
149
149
|
readonly password: false;
|
|
150
150
|
};
|
|
151
|
-
readonly
|
|
151
|
+
readonly subagent_soul: {
|
|
152
152
|
readonly label: "Update soul file";
|
|
153
153
|
readonly protected: false;
|
|
154
154
|
readonly password: false;
|
|
155
155
|
};
|
|
156
|
-
readonly
|
|
157
|
-
readonly label: "Change
|
|
156
|
+
readonly subagent_state: {
|
|
157
|
+
readonly label: "Change subagent";
|
|
158
158
|
readonly protected: false;
|
|
159
159
|
readonly password: false;
|
|
160
160
|
};
|
|
161
|
-
readonly
|
|
162
|
-
readonly label: "Tell
|
|
161
|
+
readonly subagent_note: {
|
|
162
|
+
readonly label: "Tell subagent";
|
|
163
163
|
readonly protected: false;
|
|
164
164
|
readonly password: false;
|
|
165
165
|
};
|
|
166
|
-
readonly
|
|
167
|
-
readonly label: "
|
|
166
|
+
readonly subagent_ask: {
|
|
167
|
+
readonly label: "Ask subagent";
|
|
168
168
|
readonly protected: false;
|
|
169
169
|
readonly password: false;
|
|
170
170
|
};
|
|
171
|
-
readonly
|
|
172
|
-
readonly label: "
|
|
171
|
+
readonly subagent_answer: {
|
|
172
|
+
readonly label: "Answer subagent";
|
|
173
173
|
readonly protected: false;
|
|
174
174
|
readonly password: false;
|
|
175
175
|
};
|
|
176
|
-
readonly
|
|
177
|
-
readonly label: "Change
|
|
176
|
+
readonly subagent_tools: {
|
|
177
|
+
readonly label: "Change subagent's tools";
|
|
178
178
|
readonly protected: false;
|
|
179
179
|
readonly password: false;
|
|
180
180
|
};
|
|
181
|
-
readonly
|
|
182
|
-
readonly label: "Change
|
|
181
|
+
readonly subagent_memory: {
|
|
182
|
+
readonly label: "Change subagent's memory";
|
|
183
183
|
readonly protected: false;
|
|
184
184
|
readonly password: false;
|
|
185
185
|
};
|
|
186
|
-
readonly
|
|
187
|
-
readonly label: "
|
|
186
|
+
readonly subagent_routine: {
|
|
187
|
+
readonly label: "Change subagent's routines";
|
|
188
|
+
readonly protected: false;
|
|
189
|
+
readonly password: false;
|
|
190
|
+
};
|
|
191
|
+
readonly subagent_undo: {
|
|
192
|
+
readonly label: "Undo subagent's call";
|
|
188
193
|
readonly protected: false;
|
|
189
194
|
readonly password: false;
|
|
190
195
|
};
|
|
@@ -251,7 +256,7 @@ export declare function sharedActionReviewPath(id: number): string;
|
|
|
251
256
|
export declare function mintSharedActionReview(store: Store, who: VerifiedApprover, id: number, root: string, now: Date): {
|
|
252
257
|
payload: {
|
|
253
258
|
version: 1;
|
|
254
|
-
operation: "decision_record" | "decision_retire" | "flow_card_add" | "flow_card_approve" | "flow_card_assign" | "flow_card_cancel" | "flow_card_choose" | "flow_card_comment" | "flow_card_move" | "flow_card_send_back" | "flow_card_watch" | "flow_create" | "flow_edit" | "flow_script_save" | "flow_starter" | "flow_trigger_add" | "flow_trigger_pause" | "flow_trigger_remove" | "flow_trigger_resume" | "kit_setup" | "knowledge_instructions" | "knowledge_remove" | "knowledge_restore" | "knowledge_save" | "lead_about_you" | "result_accept" | "scope_approve" | "skill_disable" | "skill_enable" | "skill_import" | "skill_restore" | "skill_test" | "
|
|
259
|
+
operation: "decision_record" | "decision_retire" | "flow_card_add" | "flow_card_approve" | "flow_card_assign" | "flow_card_cancel" | "flow_card_choose" | "flow_card_comment" | "flow_card_move" | "flow_card_send_back" | "flow_card_watch" | "flow_create" | "flow_edit" | "flow_script_save" | "flow_starter" | "flow_trigger_add" | "flow_trigger_pause" | "flow_trigger_remove" | "flow_trigger_resume" | "kit_setup" | "knowledge_instructions" | "knowledge_remove" | "knowledge_restore" | "knowledge_save" | "lead_about_you" | "result_accept" | "scope_approve" | "skill_disable" | "skill_enable" | "skill_import" | "skill_restore" | "skill_test" | "subagent_answer" | "subagent_ask" | "subagent_create" | "subagent_memory" | "subagent_note" | "subagent_routine" | "subagent_soul" | "subagent_state" | "subagent_tools" | "subagent_undo" | "task_cancel" | "task_resume" | "tool_add" | "tool_remove";
|
|
255
260
|
request: {
|
|
256
261
|
[x: string]: unknown;
|
|
257
262
|
};
|
package/dist/chat-actions.js
CHANGED
|
@@ -5,7 +5,7 @@ import { TEXT_LIMITS } from "./text-limits.js";
|
|
|
5
5
|
import { publicChatText } from "./chat-display.js";
|
|
6
6
|
import { gateWords } from "./approval-policy.js";
|
|
7
7
|
import { createHash, randomBytes } from "node:crypto";
|
|
8
|
-
import {
|
|
8
|
+
import { leadTurnKeepsProposals, verifiedAuthor } from "./store.js";
|
|
9
9
|
import { isVerifiedApprover, reproveApprover, } from "./principal.js";
|
|
10
10
|
import { changeSkills, importSkill, skillsView, skillsVersion, testSkill, validateSkill, } from "./project-skills.js";
|
|
11
11
|
import { changeKnowledge, knowledgeVersion, knowledgeView, } from "./project-knowledge.js";
|
|
@@ -25,15 +25,15 @@ import { assignFlowCard, commentOnFlowCard, flowPeople, mentionsIn, watchFlowCar
|
|
|
25
25
|
import { addFlowTriggerTo, describeTrigger, readLinearKey, removeFlowTrigger, scheduleFromWords, takesDeliveries, triggerConfigOf, validateTriggerConfig } from "./flow-triggers.js";
|
|
26
26
|
import { describeSchedule, parseSchedule } from "./flow-schedule.js";
|
|
27
27
|
import { dirname } from "node:path";
|
|
28
|
-
import { handleOf, parseSoul, SOUL_CHARS,
|
|
29
|
-
import {
|
|
30
|
-
import { cleanMemory, editMemory, forgetMemory,
|
|
31
|
-
import { addRoutine, removeRoutine, routineSchedule, routinesOf } from "./
|
|
32
|
-
import { requestUndo, undoFor } from "./
|
|
28
|
+
import { handleOf, parseSoul, SOUL_CHARS, SUBAGENT_TEMPLATES, subagentLabel } from "./subagents.js";
|
|
29
|
+
import { createSubagentFrom, labelOf, nameOf, renamedSoul, saveSoul, setSubagentState } from "./subagent-admin.js";
|
|
30
|
+
import { cleanMemory, editMemory, forgetMemory, tellSubagent } from "./subagent-memory.js";
|
|
31
|
+
import { addRoutine, askSubagent, removeRoutine, routineSchedule, routinesOf } from "./subagent-desk.js";
|
|
32
|
+
import { requestUndo, undoFor } from "./subagent-week.js";
|
|
33
33
|
import { kitInstalled, kitOf, KITS, setUpKitNow } from "./kits.js";
|
|
34
34
|
import { starterFlowOf, starterOf, startersFor, starterTerms, STARTER_FLOWS, switchOnStarter } from "./flow-starters.js";
|
|
35
|
-
import {
|
|
36
|
-
import { callWords, checkRule, defaultRule, grantListed, revokeTool, ruleWords, setToolRules } from "./
|
|
35
|
+
import { answerSubagentQuestion } from "./subagent-work.js";
|
|
36
|
+
import { callWords, checkRule, defaultRule, grantListed, revokeTool, ruleWords, setToolRules } from "./subagent-tools.js";
|
|
37
37
|
import { aboutYouOf, checkAboutYouLine, saveAboutYou, withAboutYouLine } from "./lead-about.js";
|
|
38
38
|
import { CHAT_ACTION_FIELDS, readChatActionRequest, readSharedAction, SHARED_ACTION_VERSION } from "./contracts/chat-actions.js";
|
|
39
39
|
export { CHAT_ACTION_FIELDS };
|
|
@@ -101,15 +101,16 @@ export const CHAT_ACTIONS = {
|
|
|
101
101
|
flow_trigger_pause: { label: "Pause trigger", protected: false, password: false },
|
|
102
102
|
flow_trigger_resume: { label: "Turn trigger on", protected: false, password: false },
|
|
103
103
|
flow_trigger_remove: { label: "Remove trigger", protected: false, password: false },
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
104
|
+
subagent_create: { label: "Add subagent", protected: false, password: false },
|
|
105
|
+
subagent_soul: { label: "Update soul file", protected: false, password: false },
|
|
106
|
+
subagent_state: { label: "Change subagent", protected: false, password: false },
|
|
107
|
+
subagent_note: { label: "Tell subagent", protected: false, password: false },
|
|
108
|
+
subagent_ask: { label: "Ask subagent", protected: false, password: false },
|
|
109
|
+
subagent_answer: { label: "Answer subagent", protected: false, password: false },
|
|
110
|
+
subagent_tools: { label: "Change subagent's tools", protected: false, password: false },
|
|
111
|
+
subagent_memory: { label: "Change subagent's memory", protected: false, password: false },
|
|
112
|
+
subagent_routine: { label: "Change subagent's routines", protected: false, password: false },
|
|
113
|
+
subagent_undo: { label: "Undo subagent's call", protected: false, password: false },
|
|
113
114
|
kit_setup: { label: "Set up kit", protected: false, password: false },
|
|
114
115
|
decision_record: { label: "Record decision", protected: false, password: false },
|
|
115
116
|
decision_retire: { label: "Retire decision", protected: false, password: false },
|
|
@@ -262,19 +263,19 @@ export function prepareSharedAction(store, who, operation, input, root, now = ne
|
|
|
262
263
|
const stamp = hash({ operation, request, repo: "", state, terms, actor: who.name, generation: who.generation, ceiling: who.ceilingDigest });
|
|
263
264
|
return { version: SHARED_ACTION_VERSION, operation, request, repo: "", title, terms, stamp, state };
|
|
264
265
|
}
|
|
265
|
-
const task = operation.startsWith("skill_") || operation.startsWith("knowledge_") || operation.startsWith("decision_") || operation.startsWith("tool_") || operation.startsWith("flow_") || operation.startsWith("
|
|
266
|
+
const task = operation.startsWith("skill_") || operation.startsWith("knowledge_") || operation.startsWith("decision_") || operation.startsWith("tool_") || operation.startsWith("flow_") || operation.startsWith("subagent_") || operation.startsWith("kit_")
|
|
266
267
|
? null
|
|
267
268
|
: text(input, "task", 64);
|
|
268
269
|
const flowTarget = operation.startsWith("flow_") && operation !== "flow_create" && operation !== "flow_script_save" && operation !== "flow_starter" ? flowTargetOf(store, input) : null;
|
|
269
|
-
// v92: a
|
|
270
|
-
const
|
|
271
|
-
if (
|
|
272
|
-
throw Error("That
|
|
273
|
-
const questionTarget = operation === "
|
|
270
|
+
// v92: a subagent names its project; a question names it through its card's flow.
|
|
271
|
+
const subagentTarget = operation.startsWith("subagent_") && operation !== "subagent_create" && operation !== "subagent_answer" ? store.getSubagent(integer(input, "subagent")) : null;
|
|
272
|
+
if (subagentTarget !== null && subagentTarget.state === "removed")
|
|
273
|
+
throw Error("That subagent is off the team.");
|
|
274
|
+
const questionTarget = operation === "subagent_answer" ? store.subagentQuestion(integer(input, "question")) : null;
|
|
274
275
|
const questionFlow = questionTarget === null ? null : store.getFlow(store.getFlowCard(questionTarget.card)?.flow ?? -1);
|
|
275
|
-
if (operation === "
|
|
276
|
+
if (operation === "subagent_answer" && (questionTarget === null || questionFlow === null))
|
|
276
277
|
throw Error("That question isn't open any more.");
|
|
277
|
-
const repo = flowTarget !== null ? flowTarget.flow.repo :
|
|
278
|
+
const repo = flowTarget !== null ? flowTarget.flow.repo : subagentTarget !== null ? subagentTarget.repo : questionFlow !== null ? questionFlow.repo : task === null ? text(input, "repo", 4096) : store.lookupRef(task)?.repo;
|
|
278
279
|
if (!repo)
|
|
279
280
|
throw Error("Choose an available project.");
|
|
280
281
|
requireActor(store, who, repo);
|
|
@@ -358,23 +359,23 @@ export function prepareSharedAction(store, who, operation, input, root, now = ne
|
|
|
358
359
|
}
|
|
359
360
|
}
|
|
360
361
|
else if (operation === "kit_setup") {
|
|
361
|
-
// a starter kit — its
|
|
362
|
+
// a starter kit — its subagent, its flow and its buttons.
|
|
362
363
|
const project = repo.split(/[\\/]/).filter(Boolean).at(-1) ?? repo;
|
|
363
364
|
const kit = kitOf(String(input["kit"] ?? ""));
|
|
364
365
|
if (kit === null)
|
|
365
366
|
throw Error(`Choose a kit: ${KITS.map(one => one.id).join(", ")}.`);
|
|
366
367
|
if (kitInstalled(store, kit, repo) !== null)
|
|
367
368
|
throw Error(`${kit.name} is already set up in ${project}.`);
|
|
368
|
-
const template =
|
|
369
|
+
const template = SUBAGENT_TEMPLATES.find(one => one.id === kit.subagent.template);
|
|
369
370
|
title = `Set up ${kit.name} in ${project}`;
|
|
370
|
-
terms.push(kit.promise, `Adds ${kit.
|
|
371
|
+
terms.push(kit.promise, `Adds ${kit.subagent.handle.charAt(0).toUpperCase()}${kit.subagent.handle.slice(1)} (${template?.label.toLowerCase() ?? "a subagent"}) and the ${kit.flowName} flow${kit.buttons.length === 0 ? "" : ` with its ${kit.buttons.map(one => `“${one.label}”`).join(" and ")} button`}. Nothing goes out without your approval.`);
|
|
371
372
|
state = {};
|
|
372
373
|
}
|
|
373
|
-
else if (operation.startsWith("
|
|
374
|
+
else if (operation.startsWith("subagent_")) {
|
|
374
375
|
const project = repo.split(/[\\/]/).filter(Boolean).at(-1) ?? repo;
|
|
375
|
-
const mate =
|
|
376
|
-
if (operation === "
|
|
377
|
-
const template =
|
|
376
|
+
const mate = subagentTarget;
|
|
377
|
+
if (operation === "subagent_create") {
|
|
378
|
+
const template = SUBAGENT_TEMPLATES.find(one => one.id === input["template"]);
|
|
378
379
|
const given = typeof input["soul"] === "string" && input["soul"].trim() !== "" ? text(input, "soul", SOUL_CHARS) : null;
|
|
379
380
|
if ((template === undefined) === (given === null))
|
|
380
381
|
throw Error("Start from a template, or write the whole soul file, not both.");
|
|
@@ -384,29 +385,29 @@ export function prepareSharedAction(store, who, operation, input, root, now = ne
|
|
|
384
385
|
const read = parseSoul(soul);
|
|
385
386
|
if (!read.ok)
|
|
386
387
|
throw Error(read.problem);
|
|
387
|
-
if (store.
|
|
388
|
-
throw Error(`There's already a
|
|
388
|
+
if (store.subagentByHandle(repo, handleOf(read.soul.name)) !== null)
|
|
389
|
+
throw Error(`There's already a subagent called ${read.soul.name} in ${project}.`);
|
|
389
390
|
Object.assign(request, { soul });
|
|
390
391
|
delete request["template"];
|
|
391
392
|
delete request["name"];
|
|
392
393
|
state = { handle: handleOf(read.soul.name) };
|
|
393
|
-
title = `Add ${
|
|
394
|
-
terms.push(soul.trim(), `${read.soul.name} decides only within these rules and asks you when they say to.
|
|
394
|
+
title = `Add ${subagentLabel(read.soul)} to the team in ${project}`;
|
|
395
|
+
terms.push(soul.trim(), `${read.soul.name} decides only within these rules and asks you when they say to. Subagents never approve code tasks or merges.`);
|
|
395
396
|
}
|
|
396
|
-
else if (operation === "
|
|
397
|
+
else if (operation === "subagent_soul") {
|
|
397
398
|
const soul = text(input, "soul", SOUL_CHARS);
|
|
398
399
|
const read = parseSoul(soul);
|
|
399
400
|
if (!read.ok)
|
|
400
401
|
throw Error(read.problem);
|
|
401
402
|
if (handleOf(read.soul.name) !== mate.handle)
|
|
402
|
-
throw Error("Keep the
|
|
403
|
+
throw Error("Keep the subagent's name; make a new subagent for another name.");
|
|
403
404
|
if (soul.trim() === mate.soul.trim())
|
|
404
405
|
throw Error("That's already its soul file.");
|
|
405
406
|
state = { version: mate.version };
|
|
406
|
-
title = `Update ${
|
|
407
|
+
title = `Update ${subagentLabel(read.soul)}'s soul file`;
|
|
407
408
|
terms.push(soul.trim(), `Replaces version ${mate.version}. Its next turn reads this.`);
|
|
408
409
|
}
|
|
409
|
-
else if (operation === "
|
|
410
|
+
else if (operation === "subagent_state") {
|
|
410
411
|
const wanted = input["state"];
|
|
411
412
|
if (wanted !== "active" && wanted !== "paused" && wanted !== "removed")
|
|
412
413
|
throw Error("Choose pause, resume or remove.");
|
|
@@ -414,13 +415,13 @@ export function prepareSharedAction(store, who, operation, input, root, now = ne
|
|
|
414
415
|
title = `${wanted === "paused" ? "Pause" : wanted === "active" ? "Resume" : "Remove"} ${labelOf(mate)}`;
|
|
415
416
|
terms.push(wanted === "paused" ? "Its decisions go to people and the zones it handles wait until you resume it." : wanted === "active" ? "It picks up its zones' cards again." : "It leaves the team: zones that name it go to people.");
|
|
416
417
|
}
|
|
417
|
-
else if (operation === "
|
|
418
|
+
else if (operation === "subagent_tools") {
|
|
418
419
|
// v94: which project tools it may use, and its rule for one action.
|
|
419
420
|
const tool = text(input, "tool", 40);
|
|
420
421
|
const change = input["change"];
|
|
421
|
-
const grant = store.
|
|
422
|
+
const grant = store.subagentGrant(mate.id, tool);
|
|
422
423
|
const name = nameOf(mate);
|
|
423
|
-
const grants = store.
|
|
424
|
+
const grants = store.subagentGrants(mate.id);
|
|
424
425
|
const uses = grants.length === 0 ? ` ${name} doesn't use any tools yet.` : ` ${name} uses ${grants.map(one => `${one.tool} (actions: ${one.actions.map(each => each.name).join(", ")})`).join("; ")}.`;
|
|
425
426
|
if (change === "grant") {
|
|
426
427
|
const found = projectToolsOf(store, repo).find(one => one.name === tool);
|
|
@@ -458,17 +459,17 @@ export function prepareSharedAction(store, who, operation, input, root, now = ne
|
|
|
458
459
|
else
|
|
459
460
|
throw Error("Choose grant, revoke or rule.");
|
|
460
461
|
}
|
|
461
|
-
else if (operation === "
|
|
462
|
+
else if (operation === "subagent_undo") {
|
|
462
463
|
// v97: undo one of its tool calls with the action its manager named for that.
|
|
463
|
-
const call = store.
|
|
464
|
-
const undo = call === null || call.
|
|
464
|
+
const call = store.subagentCall(integer(input, "call"));
|
|
465
|
+
const undo = call === null || call.subagent !== mate.id ? null : undoFor(store, call);
|
|
465
466
|
if (call === null || undo === null)
|
|
466
|
-
throw Error(call?.undoneBy ? `${call.undoneBy} already undid it.` : "That call can't be undone: its action has no undo set on the
|
|
467
|
+
throw Error(call?.undoneBy ? `${call.undoneBy} already undid it.` : "That call can't be undone: its action has no undo set on the subagent's Tools.");
|
|
467
468
|
title = `Undo ${nameOf(mate)}'s ${call.action}`;
|
|
468
469
|
terms.push(`Undoes: ${callWords(call.tool, call.action, call.input, 300)}`, `By calling: ${callWords(call.tool, undo, call.input, 300)}`, "It's made as you, with the same input, and both calls keep their receipts.");
|
|
469
470
|
state = { call: call.id };
|
|
470
471
|
}
|
|
471
|
-
else if (operation === "
|
|
472
|
+
else if (operation === "subagent_routine") {
|
|
472
473
|
// v96: a routine: on a schedule, a card on its desk saying what to do; its answer goes to its manager.
|
|
473
474
|
const name = nameOf(mate);
|
|
474
475
|
if (input["change"] === "add") {
|
|
@@ -494,10 +495,10 @@ export function prepareSharedAction(store, who, operation, input, root, now = ne
|
|
|
494
495
|
else
|
|
495
496
|
throw Error("Choose add or remove.");
|
|
496
497
|
}
|
|
497
|
-
else if (operation === "
|
|
498
|
+
else if (operation === "subagent_memory") {
|
|
498
499
|
// v95: edit or forget one thing it remembers.
|
|
499
|
-
const memory = store.
|
|
500
|
-
if (memory === null || memory.
|
|
500
|
+
const memory = store.subagentMemory(integer(input, "memory"));
|
|
501
|
+
if (memory === null || memory.subagent !== mate.id)
|
|
501
502
|
throw Error(`${nameOf(mate)} doesn't remember that any more.`);
|
|
502
503
|
if (input["change"] === "forget") {
|
|
503
504
|
title = `${nameOf(mate)} forgets: ${memory.text.slice(0, 60)}`;
|
|
@@ -515,12 +516,24 @@ export function prepareSharedAction(store, who, operation, input, root, now = ne
|
|
|
515
516
|
throw Error("Choose edit or forget.");
|
|
516
517
|
state = { text: memory.text };
|
|
517
518
|
}
|
|
518
|
-
else if (operation === "
|
|
519
|
+
else if (operation === "subagent_ask") {
|
|
520
|
+
// D5: the lead delegates. The card says exactly what goes to the subagent, which works it within its own rules.
|
|
521
|
+
const asked = text(input, "text", 4000).replace(/\r\n?/g, "\n").trim();
|
|
522
|
+
if (asked === "")
|
|
523
|
+
throw Error(`Say what to ask ${nameOf(mate)}.`);
|
|
524
|
+
if (mate.state !== "active")
|
|
525
|
+
throw Error(`${nameOf(mate)} is paused. Resume it first.`);
|
|
526
|
+
request["text"] = asked;
|
|
527
|
+
state = { subagent: mate.id, version: mate.version };
|
|
528
|
+
title = `Ask ${nameOf(mate)}`;
|
|
529
|
+
terms.push(asked, `${nameOf(mate)} works on it within its own rules and tools, asks you first where they say to, and its answer comes back to you. It never approves code tasks or merges.`);
|
|
530
|
+
}
|
|
531
|
+
else if (operation === "subagent_note") {
|
|
519
532
|
const note = cleanMemory(text(input, "note", 1000));
|
|
520
533
|
if (!note.ok)
|
|
521
534
|
throw Error(note.said);
|
|
522
535
|
request["note"] = note.text;
|
|
523
|
-
state = {
|
|
536
|
+
state = { subagent: mate.id };
|
|
524
537
|
title = `Tell ${nameOf(mate)}`;
|
|
525
538
|
terms.push(note.text, "It keeps this in its memory: every turn reads the latest ten things people told it.");
|
|
526
539
|
}
|
|
@@ -536,8 +549,8 @@ export function prepareSharedAction(store, who, operation, input, root, now = ne
|
|
|
536
549
|
throw Error("Pick one of its options or say the answer.");
|
|
537
550
|
Object.assign(request, { choice: choice?.id ?? null, text: said || null });
|
|
538
551
|
state = { question: question.id };
|
|
539
|
-
const
|
|
540
|
-
title = `Answer ${
|
|
552
|
+
const subagentOf = store.getSubagent(question.subagent);
|
|
553
|
+
title = `Answer ${subagentOf === null ? "the subagent" : nameOf(subagentOf)}`;
|
|
541
554
|
terms.push(question.question, `Your answer: ${[choice?.label, said].filter(Boolean).join(" — ")}`);
|
|
542
555
|
}
|
|
543
556
|
}
|
|
@@ -766,7 +779,7 @@ export function prepareSharedAction(store, who, operation, input, root, now = ne
|
|
|
766
779
|
}
|
|
767
780
|
else if (operation.startsWith("decision_")) {
|
|
768
781
|
// The staleness fence: the newest decision id and the active count, so a
|
|
769
|
-
// card drafted before a
|
|
782
|
+
// card drafted before a subagent recorded or retired one is refused.
|
|
770
783
|
const stamp = store.handle.prepare("SELECT COALESCE(MAX(id),0) AS newest, COUNT(*) AS active FROM project_decision WHERE repo=? AND status='active'").get(repo);
|
|
771
784
|
state = { newest: Number(stamp?.["newest"] ?? 0), active: Number(stamp?.["active"] ?? 0) };
|
|
772
785
|
if (operation === "decision_record") {
|
|
@@ -952,22 +965,22 @@ export function sharedActionReviewPath(id) {
|
|
|
952
965
|
function savedActionContext(store, who, id, state) {
|
|
953
966
|
if (!isVerifiedApprover(who) || !reproveApprover(store, who).ok)
|
|
954
967
|
throw Error("Your access changed. Sign in again.");
|
|
955
|
-
const proposal = store.
|
|
968
|
+
const proposal = store.getLeadProposal(id), payload = proposal?.kind === "action"
|
|
956
969
|
? sharedActionPayload(proposal.payload)
|
|
957
970
|
: null;
|
|
958
971
|
const shared = proposal && store.handle.prepare('SELECT id FROM team_conversation WHERE thread=?').get(proposal.thread);
|
|
959
|
-
const session = shared && proposal ? store.teamMateSession(who.name, proposal.thread) : store.
|
|
972
|
+
const session = shared && proposal ? store.teamMateSession(who.name, proposal.thread) : store.activeLeadSession(who.name), turn = proposal ? store.getLeadTurn(proposal.turn) : null;
|
|
960
973
|
if (!proposal ||
|
|
961
974
|
!payload ||
|
|
962
975
|
proposal.state !== state ||
|
|
963
|
-
(shared ? !store.canUseTeamMateThread(who.name, who.generation, proposal.thread) : store.
|
|
976
|
+
(shared ? !store.canUseTeamMateThread(who.name, who.generation, proposal.thread) : store.getLeadThread(proposal.thread)?.approver !== who.name))
|
|
964
977
|
throw Error("This action is no longer waiting for your review.");
|
|
965
978
|
if (!session ||
|
|
966
979
|
session.approverGeneration !== who.generation ||
|
|
967
980
|
session.ceilingDigest !== who.ceilingDigest ||
|
|
968
981
|
proposal.ceilingDigest !== who.ceilingDigest ||
|
|
969
982
|
(!shared && turn?.session !== session.id) ||
|
|
970
|
-
!
|
|
983
|
+
!leadTurnKeepsProposals(turn))
|
|
971
984
|
throw Error("This conversation ended or its project access changed. Ask for a fresh proposal.");
|
|
972
985
|
requireActor(store, who, payload.repo, payload.operation);
|
|
973
986
|
return payload;
|
|
@@ -1070,8 +1083,8 @@ export function executeSharedAction(store, who, id, payload, now, options) {
|
|
|
1070
1083
|
throw Error(made.said);
|
|
1071
1084
|
return { ok: true, taskId: null, said: `${made.said} Try it with a sample card from its page.`, href: `/kits/${kit.id}?repo=${encodeURIComponent(repo)}` };
|
|
1072
1085
|
}
|
|
1073
|
-
else if (payload.operation.startsWith("
|
|
1074
|
-
const done =
|
|
1086
|
+
else if (payload.operation.startsWith("subagent_")) {
|
|
1087
|
+
const done = runSubagentAction(store, payload, actor, now);
|
|
1075
1088
|
return { ok: true, taskId: null, said: done.said, href: done.href };
|
|
1076
1089
|
}
|
|
1077
1090
|
else if (payload.operation === "tool_add") {
|
|
@@ -1181,50 +1194,59 @@ export function executeSharedAction(store, who, id, payload, now, options) {
|
|
|
1181
1194
|
: "The action could not be completed.");
|
|
1182
1195
|
}
|
|
1183
1196
|
}
|
|
1184
|
-
/** A confirmed
|
|
1185
|
-
function
|
|
1197
|
+
/** A confirmed subagent action (v92), through the same helpers the Subagents pages use. */
|
|
1198
|
+
function runSubagentAction(store, payload, actor, now) {
|
|
1186
1199
|
const req = payload.request;
|
|
1187
|
-
if (payload.operation === "
|
|
1188
|
-
const made =
|
|
1200
|
+
if (payload.operation === "subagent_create") {
|
|
1201
|
+
const made = createSubagentFrom(store, { repo: payload.repo, soul: String(req["soul"]), by: actor }, now);
|
|
1189
1202
|
if (!made.ok)
|
|
1190
1203
|
throw Error(made.said);
|
|
1191
|
-
return { said: made.said, href: `/
|
|
1204
|
+
return { said: made.said, href: `/settings/lead/subagents/${made.id}` };
|
|
1192
1205
|
}
|
|
1193
|
-
if (payload.operation === "
|
|
1194
|
-
const question = store.
|
|
1195
|
-
const answered =
|
|
1206
|
+
if (payload.operation === "subagent_answer") {
|
|
1207
|
+
const question = store.subagentQuestion(Number(req["question"]));
|
|
1208
|
+
const answered = answerSubagentQuestion(store, Number(req["question"]), { choice: req["choice"] === null ? null : String(req["choice"]), text: req["text"] === null ? null : String(req["text"]), by: actor, via: "chat" }, now);
|
|
1196
1209
|
if (!answered.ok)
|
|
1197
1210
|
throw Error(answered.said);
|
|
1198
|
-
return { said: answered.said, href: question === null ? "/
|
|
1211
|
+
return { said: answered.said, href: question === null ? "/settings/lead/subagents" : `/settings/lead/subagents/${question.subagent}` };
|
|
1199
1212
|
}
|
|
1200
|
-
const mate = store.
|
|
1213
|
+
const mate = store.getSubagent(Number(req["subagent"]));
|
|
1201
1214
|
if (mate === null || mate.state === "removed")
|
|
1202
|
-
throw Error("That
|
|
1203
|
-
if (payload.operation === "
|
|
1215
|
+
throw Error("That subagent is off the team.");
|
|
1216
|
+
if (payload.operation === "subagent_ask") {
|
|
1217
|
+
// One card per confirmed proposal: the confirmation runs once, so a retried tap never asks twice.
|
|
1218
|
+
if (mate.version !== payload.state["version"])
|
|
1219
|
+
throw Error("Someone changed its soul file since. Ask for a fresh proposal.");
|
|
1220
|
+
const asked = askSubagent(store, mate, { who: actor, via: "the lead" }, String(req["text"]), now);
|
|
1221
|
+
if (!asked.ok)
|
|
1222
|
+
throw Error(asked.said);
|
|
1223
|
+
return { said: asked.said, href: asked.link.path };
|
|
1224
|
+
}
|
|
1225
|
+
if (payload.operation === "subagent_undo") {
|
|
1204
1226
|
const asked = requestUndo(store, mate, Number(req["call"]), actor, now);
|
|
1205
1227
|
if (!asked.ok)
|
|
1206
1228
|
throw Error(asked.said);
|
|
1207
|
-
return { said: `${asked.said} The receipt on the card shows how it went.`, href: `/
|
|
1229
|
+
return { said: `${asked.said} The receipt on the card shows how it went.`, href: `/settings/lead/subagents/${mate.id}#week` };
|
|
1208
1230
|
}
|
|
1209
|
-
if (payload.operation === "
|
|
1231
|
+
if (payload.operation === "subagent_routine") {
|
|
1210
1232
|
const done = req["change"] === "add" ? addRoutine(store, mate, String(req["schedule"]), String(req["text"]), actor, now, null)
|
|
1211
1233
|
: removeRoutine(store, mate, Number(req["routine"]), now, null);
|
|
1212
1234
|
if (!done.ok)
|
|
1213
1235
|
throw Error(done.said);
|
|
1214
|
-
return { said: done.said, href: `/
|
|
1236
|
+
return { said: done.said, href: `/settings/lead/subagents/${mate.id}#desk` };
|
|
1215
1237
|
}
|
|
1216
|
-
if (payload.operation === "
|
|
1217
|
-
const memory = store.
|
|
1238
|
+
if (payload.operation === "subagent_memory") {
|
|
1239
|
+
const memory = store.subagentMemory(Number(req["memory"]));
|
|
1218
1240
|
if (memory === null || memory.text !== payload.state["text"])
|
|
1219
1241
|
throw Error("That memory changed since. Ask for a fresh proposal.");
|
|
1220
1242
|
const done = req["change"] === "forget" ? forgetMemory(store, mate, memory.id, actor, now) : editMemory(store, mate, memory.id, String(req["text"]), actor, now);
|
|
1221
1243
|
if (!done.ok)
|
|
1222
1244
|
throw Error(done.said);
|
|
1223
|
-
return { said: done.said, href: `/
|
|
1245
|
+
return { said: done.said, href: `/settings/lead/subagents/${mate.id}#memory` };
|
|
1224
1246
|
}
|
|
1225
|
-
if (payload.operation === "
|
|
1247
|
+
if (payload.operation === "subagent_tools") {
|
|
1226
1248
|
const tool = String(req["tool"]);
|
|
1227
|
-
const grant = store.
|
|
1249
|
+
const grant = store.subagentGrant(mate.id, tool);
|
|
1228
1250
|
if ((grant === null ? "" : JSON.stringify(grant.rules)) !== payload.state["rules"])
|
|
1229
1251
|
throw Error("Someone changed its tools since. Ask for a fresh proposal.");
|
|
1230
1252
|
const found = projectToolsOf(store, mate.repo).find(one => one.name === tool);
|
|
@@ -1234,16 +1256,16 @@ function runTeammateAction(store, payload, actor, now) {
|
|
|
1234
1256
|
undo: req["undoWith"] ?? grant?.rules[String(req["action"])]?.undo ?? "" } }, actor, now);
|
|
1235
1257
|
if (!done.ok)
|
|
1236
1258
|
throw Error(done.said);
|
|
1237
|
-
return { said: done.said, href: `/
|
|
1259
|
+
return { said: done.said, href: `/settings/lead/subagents/${mate.id}#tools` };
|
|
1238
1260
|
}
|
|
1239
|
-
if (payload.operation === "
|
|
1261
|
+
if (payload.operation === "subagent_soul" && mate.version !== payload.state["version"])
|
|
1240
1262
|
throw Error("Someone changed its soul file since. Ask for a fresh proposal.");
|
|
1241
|
-
const done = payload.operation === "
|
|
1242
|
-
: payload.operation === "
|
|
1243
|
-
:
|
|
1263
|
+
const done = payload.operation === "subagent_soul" ? saveSoul(store, mate, String(req["soul"]), actor, now)
|
|
1264
|
+
: payload.operation === "subagent_state" ? setSubagentState(store, mate, req["state"], actor, now)
|
|
1265
|
+
: tellSubagent(store, mate, String(req["note"]), actor, now);
|
|
1244
1266
|
if (!done.ok)
|
|
1245
1267
|
throw Error(done.said);
|
|
1246
|
-
return { said: done.said, href: payload.operation === "
|
|
1268
|
+
return { said: done.said, href: payload.operation === "subagent_state" && req["state"] === "removed" ? "/settings/lead/subagents" : `/settings/lead/subagents/${mate.id}` };
|
|
1247
1269
|
}
|
|
1248
1270
|
/** A confirmed flow action, through the same helpers the canvas uses; then
|
|
1249
1271
|
* the flow moves what it can right away, as it does after a canvas change. */
|
package/dist/chat-ask.d.ts
CHANGED
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
* asked, and only while nobody has written in that thread since.
|
|
12
12
|
*/
|
|
13
13
|
import type { ChatBinding, ChatEvent, ChatState } from "./chat-delivery-state.js";
|
|
14
|
-
import { type
|
|
14
|
+
import { type LeadAsk, type Store } from "./store.js";
|
|
15
15
|
/** The question as text with its options, where no buttons are drawn. */
|
|
16
|
-
export declare function chatAskText(ask: Pick<
|
|
16
|
+
export declare function chatAskText(ask: Pick<LeadAsk, "question" | "options">): string;
|
|
17
17
|
/** The live buttons on one part, in the order they were minted: the options, then "Something else". None when the part
|
|
18
18
|
* is not in its owner's own chat with Toolroll (a room), where a tap could not be their message. */
|
|
19
19
|
export declare function chatAskButtons(state: ChatState, part: number, now: Date): Array<{
|