@tablation/crew 0.48.0 → 0.49.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +50 -17
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -7470,6 +7470,17 @@ import { join as join13 } from "path";
|
|
|
7470
7470
|
import { parse as parseYaml } from "yaml";
|
|
7471
7471
|
import { TablationClient as TablationClient3, StaleWriteError as StaleWriteError8, TablationApiError as TablationApiError2 } from "@tablation/client";
|
|
7472
7472
|
|
|
7473
|
+
// src/prompt-additions.ts
|
|
7474
|
+
var PROMPT_ADDITIONS_SEPARATOR = "---\n\nAdditional instructions from this workspace. Where they conflict with anything above, these take precedence.";
|
|
7475
|
+
function appendAdditions(text, additions) {
|
|
7476
|
+
if (typeof additions !== "string" || additions.trim() === "") return text;
|
|
7477
|
+
return `${text}
|
|
7478
|
+
|
|
7479
|
+
${PROMPT_ADDITIONS_SEPARATOR}
|
|
7480
|
+
|
|
7481
|
+
${additions}`;
|
|
7482
|
+
}
|
|
7483
|
+
|
|
7473
7484
|
// src/agents.ts
|
|
7474
7485
|
import { readFileSync as readFileSync10, existsSync as existsSync10 } from "fs";
|
|
7475
7486
|
import { join as join12 } from "path";
|
|
@@ -7510,9 +7521,9 @@ async function resolveAgentId(route, role, opts) {
|
|
|
7510
7521
|
return void 0;
|
|
7511
7522
|
}
|
|
7512
7523
|
}
|
|
7513
|
-
async function
|
|
7524
|
+
async function fetchPersonaPrompt(route, role, opts) {
|
|
7514
7525
|
const agentId = await resolveAgentId(route, role, opts);
|
|
7515
|
-
if (!agentId || !route.resolved) return
|
|
7526
|
+
if (!agentId || !route.resolved) return {};
|
|
7516
7527
|
const client2 = new TablationClient2({
|
|
7517
7528
|
baseUrl: `${route.baseUrl}/api`,
|
|
7518
7529
|
apiKey: resolveApiKey(route),
|
|
@@ -7525,8 +7536,17 @@ async function fetchDivergedPrompt(route, role, opts) {
|
|
|
7525
7536
|
agentsModelId = agentsModel.id;
|
|
7526
7537
|
row = await client2.records.get(agentsModelId, agentId);
|
|
7527
7538
|
} catch {
|
|
7528
|
-
return
|
|
7539
|
+
return {};
|
|
7529
7540
|
}
|
|
7541
|
+
const additions = typeof row.prompt_additions === "string" && row.prompt_additions.trim() !== "" ? row.prompt_additions : void 0;
|
|
7542
|
+
const divergedPrompt = await divergedRowPrompt(route, role, row, agentId, agentsModelId, opts);
|
|
7543
|
+
return { divergedPrompt, additions };
|
|
7544
|
+
}
|
|
7545
|
+
function personaPromptOptions(p) {
|
|
7546
|
+
return { divergedPrompt: p.divergedPrompt, personaAdditions: p.additions };
|
|
7547
|
+
}
|
|
7548
|
+
async function divergedRowPrompt(route, role, row, agentId, agentsModelId, opts) {
|
|
7549
|
+
if (!route.resolved) return void 0;
|
|
7530
7550
|
const defaultPrompt = personaDefaultPrompt(route.promptsDir, role);
|
|
7531
7551
|
if (row.prompt === defaultPrompt) return void 0;
|
|
7532
7552
|
const cached = route.resolved.agentPersonas?.[role];
|
|
@@ -7572,8 +7592,8 @@ async function fetchSeatPersona(route, role, opts) {
|
|
|
7572
7592
|
}
|
|
7573
7593
|
}
|
|
7574
7594
|
async function currentPersonaPrompt(route, role, opts) {
|
|
7575
|
-
const
|
|
7576
|
-
return
|
|
7595
|
+
const { divergedPrompt, additions } = await fetchPersonaPrompt(route, role, opts);
|
|
7596
|
+
return appendAdditions(divergedPrompt ?? personaDefaultPrompt(route.promptsDir, role), additions);
|
|
7577
7597
|
}
|
|
7578
7598
|
async function fetchHistoryEntries(route, agentsModelId, recordId, userAgent, limit = 50) {
|
|
7579
7599
|
const url = `${route.baseUrl.replace(/\/+$/, "")}/api/data-models/${agentsModelId}/records/${recordId}/history?limit=${limit}`;
|
|
@@ -8031,14 +8051,18 @@ async function fetchSkillOverrides(route, opts) {
|
|
|
8031
8051
|
const out = {};
|
|
8032
8052
|
for (const row of rows) {
|
|
8033
8053
|
const name = row.name;
|
|
8034
|
-
|
|
8035
|
-
|
|
8036
|
-
const
|
|
8037
|
-
if (
|
|
8038
|
-
out[name] = row.prompt;
|
|
8054
|
+
const edited = isEditedSkillRow(row, local.get(name)?.prompt, cache[name]);
|
|
8055
|
+
const base = edited ? row.prompt : local.get(name)?.prompt ?? row.prompt;
|
|
8056
|
+
const composed = appendAdditions(base, row.prompt_additions);
|
|
8057
|
+
if (edited || composed !== base) out[name] = composed;
|
|
8039
8058
|
}
|
|
8040
8059
|
return out;
|
|
8041
8060
|
}
|
|
8061
|
+
function isEditedSkillRow(row, localPrompt, cached) {
|
|
8062
|
+
if (row.prompt === localPrompt) return false;
|
|
8063
|
+
if (row.prompt_customized !== true && row.prompt === row.prompt_baseline) return false;
|
|
8064
|
+
return !(cached?.skillId === row.id && cached.lastSyncedUpdatedAt === row.updated_at);
|
|
8065
|
+
}
|
|
8042
8066
|
function skillMarkerWarnings(promptsDir, personaPrompts) {
|
|
8043
8067
|
const shipped = new Set(listLocalSkills(promptsDir).map((s) => s.name));
|
|
8044
8068
|
const out = [];
|
|
@@ -8122,7 +8146,7 @@ function planAgentRun(o) {
|
|
|
8122
8146
|
const common = usesCommon ? readFileSync12(commonPath, "utf8") : "";
|
|
8123
8147
|
const brief = readFileSync12(briefPath, "utf8");
|
|
8124
8148
|
const effectiveCommon = o.divergedPrompt ? "" : common;
|
|
8125
|
-
const effectiveBrief = o.divergedPrompt ?? brief;
|
|
8149
|
+
const effectiveBrief = appendAdditions(o.divergedPrompt ?? brief, o.personaAdditions);
|
|
8126
8150
|
const localSkills = new Map(listLocalSkills(o.route.promptsDir).map((s) => [s.name, s.prompt]));
|
|
8127
8151
|
let expanded;
|
|
8128
8152
|
try {
|
|
@@ -8667,8 +8691,13 @@ ${v.reason[0].toUpperCase()}${v.reason.slice(1)}. Set back to \`in_progress\`, s
|
|
|
8667
8691
|
async function enforceHandoff(i) {
|
|
8668
8692
|
try {
|
|
8669
8693
|
const t = await i.writer.ticket(i.ticketId);
|
|
8670
|
-
|
|
8694
|
+
const st = i.contract.statuses;
|
|
8671
8695
|
const log = { ticket: t.issue_id, step: "handoff" };
|
|
8696
|
+
const claimed = [st.verifying, st.verified, st.deployed].some((s) => s && t.status === s);
|
|
8697
|
+
if (t.status !== st.handoff && !claimed) {
|
|
8698
|
+
i.log.emit(`${t.issue_id} is at ${t.status}, not handed off \u2014 nothing to check`, log);
|
|
8699
|
+
return { kind: "not-handed-off" };
|
|
8700
|
+
}
|
|
8672
8701
|
const v = inspectHandoff(i.dir, i.cfg, t, i.role);
|
|
8673
8702
|
if (v.kind === "unverified") {
|
|
8674
8703
|
i.log.warn(`${t.issue_id} is at ${t.status} but the push was not checked: ${v.why}`, log);
|
|
@@ -8679,6 +8708,10 @@ async function enforceHandoff(i) {
|
|
|
8679
8708
|
i.log.emit(`${t.issue_id} pushed at ${v.sha.slice(0, 7)} \u2014 handed on to QA`, log);
|
|
8680
8709
|
return { kind: "pushed", sha: v.sha };
|
|
8681
8710
|
}
|
|
8711
|
+
if (claimed) {
|
|
8712
|
+
i.log.warn(`${t.issue_id} is at ${t.status} but its branch is not on the remote at HEAD: ${v.reason}`, log);
|
|
8713
|
+
return { kind: "failed", why: v.reason };
|
|
8714
|
+
}
|
|
8682
8715
|
const heldBy = i.hold ? t[i.hold.column] : void 0;
|
|
8683
8716
|
await i.writer.updateTicket(t.id, {
|
|
8684
8717
|
status: i.contract.statuses.building,
|
|
@@ -11196,7 +11229,7 @@ async function showLogEntry(route, entryId, opts = {}) {
|
|
|
11196
11229
|
}
|
|
11197
11230
|
};
|
|
11198
11231
|
}
|
|
11199
|
-
const prompt = match.prompt ?? "";
|
|
11232
|
+
const prompt = appendAdditions(match.prompt ?? "", match.prompt_additions);
|
|
11200
11233
|
const actualSha = createHash3("sha256").update(prompt).digest("hex");
|
|
11201
11234
|
const exact = !!entry.prompt_sha && actualSha === entry.prompt_sha;
|
|
11202
11235
|
return {
|
|
@@ -12665,7 +12698,7 @@ async function runRoleAgent(role, decision, ctx) {
|
|
|
12665
12698
|
cycle: emit.cycle,
|
|
12666
12699
|
ticket: ticketHint,
|
|
12667
12700
|
repo: ticketRepo,
|
|
12668
|
-
|
|
12701
|
+
...personaPromptOptions(await fetchPersonaPrompt(route, role, { userAgent: ship.userAgent })),
|
|
12669
12702
|
skillOverrides: await fetchSkillOverrides(route, { userAgent: ship.userAgent }),
|
|
12670
12703
|
agentPersona: await fetchSeatPersona(route, role, { userAgent: ship.userAgent }),
|
|
12671
12704
|
resolvedAgentId: await resolveAgentId(route, role, { userAgent: ship.userAgent })
|
|
@@ -13844,7 +13877,7 @@ ${changed2.map((c) => ` - ${c}
|
|
|
13844
13877
|
cycle: wemit.cycle,
|
|
13845
13878
|
ticket: w.decision.actionable.top?.issue_id,
|
|
13846
13879
|
repo: repoTargetFor(w.route, w.decision.actionable.top?.repo_id)?.name,
|
|
13847
|
-
|
|
13880
|
+
...personaPromptOptions(await fetchPersonaPrompt(w.route, w.role, { userAgent: cfg.ship.userAgent })),
|
|
13848
13881
|
skillOverrides: await fetchSkillOverrides(w.route, { userAgent: cfg.ship.userAgent }),
|
|
13849
13882
|
agentPersona: await fetchSeatPersona(w.route, w.role, { userAgent: cfg.ship.userAgent }),
|
|
13850
13883
|
resolvedAgentId: await resolveAgentId(w.route, w.role, { userAgent: cfg.ship.userAgent })
|
|
@@ -13941,7 +13974,7 @@ ${changed2.map((c) => ` - ${c}
|
|
|
13941
13974
|
cycle: wemit.cycle,
|
|
13942
13975
|
ticket: fleetTicketHint,
|
|
13943
13976
|
repo: fleetTicketRepo,
|
|
13944
|
-
|
|
13977
|
+
...personaPromptOptions(await fetchPersonaPrompt(w.route, w.role, { userAgent: cfg.ship.userAgent })),
|
|
13945
13978
|
skillOverrides: await fetchSkillOverrides(w.route, { userAgent: cfg.ship.userAgent }),
|
|
13946
13979
|
agentPersona: await fetchSeatPersona(w.route, w.role, { userAgent: cfg.ship.userAgent }),
|
|
13947
13980
|
resolvedAgentId: await resolveAgentId(w.route, w.role, { userAgent: cfg.ship.userAgent })
|
|
@@ -14150,7 +14183,7 @@ ${changed2.map((c) => ` - ${c}
|
|
|
14150
14183
|
cycle: emit.cycle,
|
|
14151
14184
|
ticket: ticketHint,
|
|
14152
14185
|
repo: ticketRepo,
|
|
14153
|
-
|
|
14186
|
+
...personaPromptOptions(await fetchPersonaPrompt(route, current, { userAgent: cfg.ship.userAgent })),
|
|
14154
14187
|
skillOverrides: await fetchSkillOverrides(route, { userAgent: cfg.ship.userAgent }),
|
|
14155
14188
|
agentPersona: await fetchSeatPersona(route, current, { userAgent: cfg.ship.userAgent }),
|
|
14156
14189
|
resolvedAgentId: await resolveAgentId(route, current, { userAgent: cfg.ship.userAgent })
|
package/package.json
CHANGED