@cohortapp/agent-sdk 2.4.0 → 2.4.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.
@@ -186,7 +186,17 @@ export function mapProfileToAgentConfig(profile) {
186
186
  // the "Background" section of the prompt persona block (lib/identity/persona.mjs)
187
187
  // so the agent writes with its own history behind it rather than as a generic
188
188
  // seat-holder. The org is the SoT for this; we never synthesise one.
189
- const persona = sectionText(sections, ["persona", "background", "bio", "about", "profile"]);
189
+ // Real Cohort records put this prose in one of two places, and the section
190
+ // list alone missed both for a live seat: the section is named SUMMARY (not
191
+ // "persona"/"background"), and the DTO also carries a top-level `bio` with the
192
+ // same text. Missing it is not cosmetic — an empty persona leaves
193
+ // `{{agent.persona}}` unresolved in CLAUDE.md and drops the Background line
194
+ // from the prompt block, which is the exact "generic assistant" failure this
195
+ // whole change exists to remove. Section first (it is the richer, explicitly
196
+ // authored field), then the top-level bio.
197
+ const persona =
198
+ sectionText(sections, ["persona", "background", "bio", "about", "profile", "summary"]) ||
199
+ str(p.bio);
190
200
  if (persona) patch.persona = persona;
191
201
 
192
202
  // charter — the Cohort-authored operating charter (CharterDTO:
@@ -345,7 +355,17 @@ function findSection(sections, names) {
345
355
  const id = str(s.id).toLowerCase();
346
356
  const title = str(s.title).toLowerCase();
347
357
  const heading = str(s.heading).toLowerCase();
348
- return wanted.includes(id) || wanted.includes(title) || wanted.includes(heading);
358
+ // `kind` is what a real Cohort ProfileSection identifies itself by
359
+ // (SUMMARY, VISUAL_PROMPT, COUNTERPARTS_NARRATIVE). Matching only
360
+ // id/title/heading silently missed EVERY section on a live seat, so a
361
+ // fully-populated org profile still yielded an empty persona.
362
+ const kind = str(s.kind).toLowerCase();
363
+ return (
364
+ wanted.includes(id) ||
365
+ wanted.includes(title) ||
366
+ wanted.includes(heading) ||
367
+ wanted.includes(kind)
368
+ );
349
369
  }) || null
350
370
  );
351
371
  }
@@ -273,3 +273,28 @@ test("pullAndPlan: a local override is NOT clobbered without --force", async ()
273
273
  const forced = await pullAndPlan({ agentRoot: root, env, force: true, fetchSelfProfileImpl: async () => ({ ok: true, result: PROFILE }) });
274
274
  assert.equal(forced.patch.title, "VP of Engineering", "--force overwrites");
275
275
  });
276
+
277
+ test("persona falls back to the SUMMARY section and then the top-level bio", () => {
278
+ // A live Cohort seat had its prose in a section named SUMMARY and in the
279
+ // DTO's top-level `bio` — neither of which the original name list matched.
280
+ // The result was an empty persona, an unresolved {{agent.persona}} in
281
+ // CLAUDE.md, and no Background line in the prompt: exactly the generic-seat
282
+ // failure this mapping exists to prevent.
283
+ const fromSummary = mapProfileToAgentConfig({
284
+ profileSections: [{ kind: "SUMMARY", body: "I build the agent substrate." }],
285
+ });
286
+ assert.equal(fromSummary.persona, "I build the agent substrate.");
287
+
288
+ const fromBio = mapProfileToAgentConfig({ bio: "I run platform engineering." });
289
+ assert.equal(fromBio.persona, "I run platform engineering.");
290
+
291
+ // An explicitly authored section still wins over the terser bio.
292
+ const both = mapProfileToAgentConfig({
293
+ bio: "short bio",
294
+ profileSections: [{ kind: "background", body: "the long authored version" }],
295
+ });
296
+ assert.equal(both.persona, "the long authored version");
297
+
298
+ // Nothing to say stays empty — we never synthesise a persona.
299
+ assert.equal(mapProfileToAgentConfig({}).persona, undefined);
300
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cohortapp/agent-sdk",
3
- "version": "2.4.0",
3
+ "version": "2.4.1",
4
4
  "description": "Cohort Agent SDK \u2014 autonomous AI colleague runtime. Deploy senior AI colleagues on dedicated Mac minis, wired to the Cohort operating surface.",
5
5
  "type": "module",
6
6
  "bin": {