@grackle-ai/prompt 0.83.1 → 0.84.0

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/README.md CHANGED
@@ -14,22 +14,44 @@ System prompt assembly and persona resolution for [Grackle](https://github.com/n
14
14
 
15
15
  ## Overview
16
16
 
17
- This package prepares everything an agent session needs before it starts:
17
+ This package is a **pure, zero-dependency** library for building agent session prompts. It has no database or store imports — callers provide pre-fetched data.
18
18
 
19
19
  - **System prompt building** — `SystemPromptBuilder` assembles prompts from discrete sections based on session type (orchestrator, leaf task, or ad-hoc). Orchestrator tasks get project context, task trees, persona rosters, and decomposition guidelines. Leaf tasks get a completion contract.
20
- - **Orchestrator context** — `fetchOrchestratorContext()` gathers all data needed for orchestrator prompts from the database: workspace metadata, task hierarchy, available personas/environments, and recent findings.
21
- - **Persona resolution** — `resolvePersona()` resolves which persona to use via a cascade: request persona task default workspace default app default.
20
+ - **Orchestrator context** — `buildOrchestratorContext()` transforms pre-fetched data (tasks, personas, environments, findings) into the slim types needed by `SystemPromptBuilder`.
21
+ - **Persona resolution** — `resolvePersona()` resolves which persona to use via a cascade: request persona, task default, workspace default, app default. Accepts a lookup function instead of accessing the database directly.
22
22
 
23
23
  ## Usage
24
24
 
25
25
  ```typescript
26
- import { SystemPromptBuilder, fetchOrchestratorContext, resolvePersona } from "@grackle-ai/prompt";
26
+ import {
27
+ SystemPromptBuilder,
28
+ buildOrchestratorContext,
29
+ resolvePersona,
30
+ } from "@grackle-ai/prompt";
27
31
 
28
- // Resolve the persona for a session
29
- const resolved = resolvePersona(requestPersonaId, taskDefaultPersonaId, workspaceDefaultPersonaId);
32
+ // Resolve the persona for a session (caller maps DB row to PersonaResolveInput)
33
+ const resolved = resolvePersona(
34
+ requestPersonaId,
35
+ taskDefaultPersonaId,
36
+ workspaceDefaultPersonaId,
37
+ appDefaultPersonaId,
38
+ (id) => {
39
+ const row = personaStore.getPersona(id);
40
+ if (!row) return undefined;
41
+ return { id: row.id, name: row.name, runtime: row.runtime, model: row.model,
42
+ maxTurns: row.maxTurns, systemPrompt: row.systemPrompt, toolConfig: row.toolConfig,
43
+ mcpServers: row.mcpServers, type: row.type, script: row.script };
44
+ },
45
+ );
30
46
 
31
- // Fetch orchestrator context (for orchestrator tasks)
32
- const context = fetchOrchestratorContext(workspaceId);
47
+ // Build orchestrator context from pre-fetched data
48
+ const context = buildOrchestratorContext({
49
+ workspace: { name: "My Project", description: "...", repoUrl: "..." },
50
+ tasks: [...], // TaskInput[]
51
+ personas: [...], // PersonaInput[]
52
+ environments: [...], // EnvironmentInput[]
53
+ findings: [...], // FindingInput[]
54
+ });
33
55
 
34
56
  // Build the system prompt
35
57
  const builder = new SystemPromptBuilder({
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { SystemPromptBuilder, buildTaskPrompt } from "./system-prompt-builder.js";
2
2
  export type { SystemPromptOptions, TaskTreeNode, PersonaSummary, EnvironmentSummary } from "./system-prompt-builder.js";
3
- export { fetchOrchestratorContext } from "./orchestrator-context.js";
4
- export type { OrchestratorContext } from "./orchestrator-context.js";
3
+ export { buildOrchestratorContext } from "./orchestrator-context.js";
4
+ export type { OrchestratorContext, OrchestratorContextInput, TaskInput, PersonaInput, EnvironmentInput, FindingInput } from "./orchestrator-context.js";
5
5
  export { resolvePersona } from "./resolve-persona.js";
6
- export type { ResolvedPersona } from "./resolve-persona.js";
6
+ export type { ResolvedPersona, PersonaResolveInput } from "./resolve-persona.js";
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClF,YAAY,EAAE,mBAAmB,EAAE,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGxH,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,YAAY,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAGrE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClF,YAAY,EAAE,mBAAmB,EAAE,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGxH,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,YAAY,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGxJ,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // ─── System Prompt Builder ──────────────────────────────────
2
2
  export { SystemPromptBuilder, buildTaskPrompt } from "./system-prompt-builder.js";
3
3
  // ─── Orchestrator Context ───────────────────────────────────
4
- export { fetchOrchestratorContext } from "./orchestrator-context.js";
4
+ export { buildOrchestratorContext } from "./orchestrator-context.js";
5
5
  // ─── Persona Resolution ────────────────────────────────────
6
6
  export { resolvePersona } from "./resolve-persona.js";
7
7
  //# sourceMappingURL=index.js.map
@@ -1,10 +1,80 @@
1
1
  /**
2
- * Fetches and assembles all data needed for the orchestrator system prompt.
3
- * Centralizes store reads so both gRPC and WebSocket call sites share
4
- * the same data-fetching logic.
2
+ * Builds the orchestrator context from pre-fetched data.
3
+ * Pure function no database or store dependencies.
5
4
  */
6
5
  import type { TaskTreeNode, PersonaSummary, EnvironmentSummary } from "./system-prompt-builder.js";
7
- /** Pre-fetched orchestrator data matching SystemPromptOptions fields. */
6
+ /** Pre-parsed task data for building orchestrator context. */
7
+ export interface TaskInput {
8
+ /** Task ID. */
9
+ id: string;
10
+ /** Task title. */
11
+ title: string;
12
+ /** Current lifecycle status. */
13
+ status: string;
14
+ /** Nesting depth in the hierarchy (0 = root). */
15
+ depth: number;
16
+ /** Parent task ID (empty string for root-level tasks). */
17
+ parentTaskId: string;
18
+ /** IDs of tasks this task depends on (pre-parsed from JSON). */
19
+ dependsOn: string[];
20
+ /** Default persona ID for this task. */
21
+ defaultPersonaId: string;
22
+ /** Git branch name (empty if none). */
23
+ branch: string;
24
+ /** Whether this task can create subtasks. */
25
+ canDecompose: boolean;
26
+ }
27
+ /** Persona data for building orchestrator context. */
28
+ export interface PersonaInput {
29
+ /** Persona ID. */
30
+ id: string;
31
+ /** Display name. */
32
+ name: string;
33
+ /** Short description. */
34
+ description: string;
35
+ /** Runtime backend. */
36
+ runtime: string;
37
+ /** Default model. */
38
+ model: string;
39
+ }
40
+ /** Environment data for building orchestrator context. */
41
+ export interface EnvironmentInput {
42
+ /** Human-readable name. */
43
+ displayName: string;
44
+ /** Adapter backend (local, ssh, codespace, docker). */
45
+ adapterType: string;
46
+ /** Connection status. */
47
+ status: string;
48
+ /** Default runtime for this environment. */
49
+ defaultRuntime: string;
50
+ }
51
+ /** Finding data for building orchestrator context. */
52
+ export interface FindingInput {
53
+ /** Finding category (decision, bug, pattern, etc.). */
54
+ category: string;
55
+ /** Finding title. */
56
+ title: string;
57
+ /** Finding content. */
58
+ content: string;
59
+ }
60
+ /** All input data needed to build orchestrator context. */
61
+ export interface OrchestratorContextInput {
62
+ /** Workspace metadata (undefined when workspace not found). */
63
+ workspace?: {
64
+ name: string;
65
+ description: string;
66
+ repoUrl: string;
67
+ };
68
+ /** All tasks in the workspace. */
69
+ tasks: TaskInput[];
70
+ /** All available personas. */
71
+ personas: PersonaInput[];
72
+ /** All available environments. */
73
+ environments: EnvironmentInput[];
74
+ /** Recent findings for the workspace. */
75
+ findings: FindingInput[];
76
+ }
77
+ /** Pre-built orchestrator data matching SystemPromptOptions fields. */
8
78
  export interface OrchestratorContext {
9
79
  /** Workspace metadata (undefined when workspace not found). */
10
80
  workspace?: {
@@ -22,10 +92,10 @@ export interface OrchestratorContext {
22
92
  findingsContext: string;
23
93
  }
24
94
  /**
25
- * Fetch all data needed for an orchestrator system prompt.
95
+ * Build orchestrator context from pre-fetched data.
26
96
  *
27
- * @param workspaceId - The workspace to scope task/findings queries to.
97
+ * @param input - Pre-fetched workspace, task, persona, environment, and finding data.
28
98
  * @returns Data ready to spread into SystemPromptOptions.
29
99
  */
30
- export declare function fetchOrchestratorContext(workspaceId: string): OrchestratorContext | undefined;
100
+ export declare function buildOrchestratorContext(input: OrchestratorContextInput): OrchestratorContext;
31
101
  //# sourceMappingURL=orchestrator-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator-context.d.ts","sourceRoot":"","sources":["../src/orchestrator-context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGnG,yEAAyE;AACzE,MAAM,WAAW,mBAAmB;IAClC,+DAA+D;IAC/D,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,uDAAuD;IACvD,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,8BAA8B;IAC9B,iBAAiB,EAAE,cAAc,EAAE,CAAC;IACpC,kCAAkC;IAClC,qBAAqB,EAAE,kBAAkB,EAAE,CAAC;IAC5C,yCAAyC;IACzC,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CA8D7F"}
1
+ {"version":3,"file":"orchestrator-context.d.ts","sourceRoot":"","sources":["../src/orchestrator-context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAInG,8DAA8D;AAC9D,MAAM,WAAW,SAAS;IACxB,eAAe;IACf,EAAE,EAAE,MAAM,CAAC;IACX,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,YAAY,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,wCAAwC;IACxC,gBAAgB,EAAE,MAAM,CAAC;IACzB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,kBAAkB;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,0DAA0D;AAC1D,MAAM,WAAW,gBAAgB;IAC/B,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,2DAA2D;AAC3D,MAAM,WAAW,wBAAwB;IACvC,+DAA+D;IAC/D,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,kCAAkC;IAClC,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,8BAA8B;IAC9B,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,kCAAkC;IAClC,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,yCAAyC;IACzC,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,uEAAuE;AACvE,MAAM,WAAW,mBAAmB;IAClC,+DAA+D;IAC/D,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,uDAAuD;IACvD,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,8BAA8B;IAC9B,iBAAiB,EAAE,cAAc,EAAE,CAAC;IACpC,kCAAkC;IAClC,qBAAqB,EAAE,kBAAkB,EAAE,CAAC;IAC5C,yCAAyC;IACzC,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,wBAAwB,GAAG,mBAAmB,CA8C7F"}
@@ -1,60 +1,45 @@
1
- import { taskStore, personaStore, envRegistry, findingStore, workspaceStore, safeParseJsonArray } from "@grackle-ai/database";
2
1
  /**
3
- * Fetch all data needed for an orchestrator system prompt.
2
+ * Build orchestrator context from pre-fetched data.
4
3
  *
5
- * @param workspaceId - The workspace to scope task/findings queries to.
4
+ * @param input - Pre-fetched workspace, task, persona, environment, and finding data.
6
5
  * @returns Data ready to spread into SystemPromptOptions.
7
6
  */
8
- export function fetchOrchestratorContext(workspaceId) {
9
- // No workspaceno orchestrator context (root/System task)
10
- if (!workspaceId) {
11
- return undefined;
12
- }
13
- // Workspace metadata
14
- const ws = workspaceStore.getWorkspace(workspaceId);
15
- // All personas (used for both the roster and persona name resolution)
16
- const allPersonas = personaStore.listPersonas();
7
+ export function buildOrchestratorContext(input) {
8
+ // Build persona ID name map for task tree persona name resolution
17
9
  const personaNameMap = new Map();
18
- for (const p of allPersonas) {
10
+ for (const p of input.personas) {
19
11
  personaNameMap.set(p.id, p.name);
20
12
  }
21
- // All tasks in this workspace → TaskTreeNode[]
22
- const allTasks = taskStore.listTasks(workspaceId || undefined);
23
- const taskTree = allTasks.map((t) => ({
13
+ // Map tasks → TaskTreeNode[]
14
+ const taskTree = input.tasks.map((t) => ({
24
15
  id: t.id,
25
16
  title: t.title,
26
17
  status: t.status,
27
18
  depth: t.depth,
28
19
  parentTaskId: t.parentTaskId,
29
- dependsOn: safeParseJsonArray(t.dependsOn),
20
+ dependsOn: t.dependsOn,
30
21
  personaName: personaNameMap.get(t.defaultPersonaId) || "",
31
22
  branch: t.branch,
32
23
  canDecompose: t.canDecompose,
33
24
  }));
34
- // Available personas
35
- const availablePersonas = allPersonas.map((p) => ({
25
+ // Map personas → PersonaSummary[]
26
+ const availablePersonas = input.personas.map((p) => ({
36
27
  name: p.name,
37
28
  description: p.description,
38
29
  runtime: p.runtime,
39
30
  model: p.model,
40
31
  }));
41
- // Available environments
42
- const availableEnvironments = envRegistry.listEnvironments().map((e) => ({
32
+ // Map environments → EnvironmentSummary[]
33
+ const availableEnvironments = input.environments.map((e) => ({
43
34
  displayName: e.displayName,
44
35
  adapterType: e.adapterType,
45
36
  status: e.status,
46
37
  defaultRuntime: e.defaultRuntime,
47
38
  }));
48
- // Findings context (pre-formatted markdown with 8K char budget)
49
- const findingsContext = workspaceId
50
- ? buildFindingsContext(workspaceId)
51
- : "";
39
+ // Build findings context (pre-formatted markdown with 8K char budget)
40
+ const findingsContext = buildFindingsContext(input.findings);
52
41
  return {
53
- workspace: ws ? {
54
- name: ws.name,
55
- description: ws.description,
56
- repoUrl: ws.repoUrl,
57
- } : undefined,
42
+ workspace: input.workspace,
58
43
  taskTree,
59
44
  availablePersonas,
60
45
  availableEnvironments,
@@ -66,15 +51,14 @@ export function fetchOrchestratorContext(workspaceId) {
66
51
  const FINDINGS_MAX_CHARS = 8000;
67
52
  /** Maximum characters per individual finding's content. */
68
53
  const FINDINGS_MAX_PER_FINDING = 500;
69
- /** Build a summarized text context of recent findings for a workspace. */
70
- function buildFindingsContext(workspaceId) {
71
- const allFindings = findingStore.queryFindings(workspaceId, undefined, undefined, 20);
72
- if (allFindings.length === 0) {
54
+ /** Build a summarized text context of recent findings. */
55
+ function buildFindingsContext(findings) {
56
+ if (findings.length === 0) {
73
57
  return "";
74
58
  }
75
59
  const lines = ["## Workspace Findings (shared knowledge from other agents)\n"];
76
60
  let totalChars = lines[0].length;
77
- for (const f of allFindings) {
61
+ for (const f of findings) {
78
62
  const content = f.content.length > FINDINGS_MAX_PER_FINDING
79
63
  ? f.content.slice(0, FINDINGS_MAX_PER_FINDING) + "..."
80
64
  : f.content;
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator-context.js","sourceRoot":"","sources":["../src/orchestrator-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"orchestrator-context.js","sourceRoot":"","sources":["../src/orchestrator-context.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,30 @@
1
- import type { PersonaRow } from "@grackle-ai/database";
1
+ /**
2
+ * Persona resolution with cascade logic.
3
+ * Pure function — no database or store dependencies.
4
+ */
5
+ /** Database-agnostic persona data for resolution. */
6
+ export interface PersonaResolveInput {
7
+ /** Persona ID. */
8
+ id: string;
9
+ /** Display name. */
10
+ name: string;
11
+ /** Agent runtime implementation (e.g. "claude-code", "codex", "genaiscript"). */
12
+ runtime: string;
13
+ /** LLM model identifier (e.g. "sonnet", "gpt-4.1"). */
14
+ model: string;
15
+ /** Maximum turns for the agent session (0 = unlimited). */
16
+ maxTurns: number;
17
+ /** System prompt to prepend. */
18
+ systemPrompt: string;
19
+ /** JSON tool configuration. */
20
+ toolConfig: string;
21
+ /** JSON array of MCP server configs. */
22
+ mcpServers: string;
23
+ /** Persona type: "agent" (interactive LLM session) or "script" (run-to-completion). */
24
+ type: string;
25
+ /** Script source code (non-empty for script personas). */
26
+ script: string;
27
+ }
2
28
  /** Resolved persona fields needed to start a session. */
3
29
  export interface ResolvedPersona {
4
30
  /** The persona ID that was resolved. */
@@ -19,15 +45,20 @@ export interface ResolvedPersona {
19
45
  type: string;
20
46
  /** Script source code (non-empty for script personas). */
21
47
  script: string;
22
- /** The full persona row for additional fields. */
23
- persona: PersonaRow;
24
48
  }
25
49
  /**
26
50
  * Resolve a persona using the cascade:
27
- * request persona task default workspace default app default error
51
+ * request persona, task default, workspace default, app default, then error
52
+ *
53
+ * The first non-empty persona ID in the cascade is used to look up the persona
54
+ * via the provided lookup function. Throws if no persona ID is found at any
55
+ * level, or if the resolved ID does not exist.
28
56
  *
29
- * The first non-empty persona ID in the cascade is used to look up the persona.
30
- * Throws if no persona ID is found at any level, or if the resolved ID does not exist.
57
+ * @param requestPersonaId - Persona ID from the request (highest priority).
58
+ * @param taskDefaultPersonaId - Task-level default persona ID.
59
+ * @param workspaceDefaultPersonaId - Workspace-level default persona ID.
60
+ * @param appDefaultPersonaId - App-level default persona ID (pre-fetched from settings).
61
+ * @param lookupPersona - Function to look up a persona by ID. Returns undefined if not found.
31
62
  */
32
- export declare function resolvePersona(requestPersonaId: string, taskDefaultPersonaId?: string, workspaceDefaultPersonaId?: string): ResolvedPersona;
63
+ export declare function resolvePersona(requestPersonaId: string, taskDefaultPersonaId: string | undefined, workspaceDefaultPersonaId: string | undefined, appDefaultPersonaId: string | undefined, lookupPersona: (id: string) => PersonaResolveInput | undefined): ResolvedPersona;
33
64
  //# sourceMappingURL=resolve-persona.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-persona.d.ts","sourceRoot":"","sources":["../src/resolve-persona.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,yDAAyD;AACzD,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,OAAO,EAAE,UAAU,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,gBAAgB,EAAE,MAAM,EACxB,oBAAoB,CAAC,EAAE,MAAM,EAC7B,yBAAyB,CAAC,EAAE,MAAM,GACjC,eAAe,CAyCjB"}
1
+ {"version":3,"file":"resolve-persona.d.ts","sourceRoot":"","sources":["../src/resolve-persona.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qDAAqD;AACrD,MAAM,WAAW,mBAAmB;IAClC,kBAAkB;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,yDAAyD;AACzD,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,gBAAgB,EAAE,MAAM,EACxB,oBAAoB,EAAE,MAAM,GAAG,SAAS,EACxC,yBAAyB,EAAE,MAAM,GAAG,SAAS,EAC7C,mBAAmB,EAAE,MAAM,GAAG,SAAS,EACvC,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,mBAAmB,GAAG,SAAS,GAC7D,eAAe,CAwCjB"}
@@ -1,21 +1,31 @@
1
- import { personaStore, settingsStore } from "@grackle-ai/database";
1
+ /**
2
+ * Persona resolution with cascade logic.
3
+ * Pure function — no database or store dependencies.
4
+ */
2
5
  /**
3
6
  * Resolve a persona using the cascade:
4
- * request persona task default workspace default app default error
7
+ * request persona, task default, workspace default, app default, then error
8
+ *
9
+ * The first non-empty persona ID in the cascade is used to look up the persona
10
+ * via the provided lookup function. Throws if no persona ID is found at any
11
+ * level, or if the resolved ID does not exist.
5
12
  *
6
- * The first non-empty persona ID in the cascade is used to look up the persona.
7
- * Throws if no persona ID is found at any level, or if the resolved ID does not exist.
13
+ * @param requestPersonaId - Persona ID from the request (highest priority).
14
+ * @param taskDefaultPersonaId - Task-level default persona ID.
15
+ * @param workspaceDefaultPersonaId - Workspace-level default persona ID.
16
+ * @param appDefaultPersonaId - App-level default persona ID (pre-fetched from settings).
17
+ * @param lookupPersona - Function to look up a persona by ID. Returns undefined if not found.
8
18
  */
9
- export function resolvePersona(requestPersonaId, taskDefaultPersonaId, workspaceDefaultPersonaId) {
19
+ export function resolvePersona(requestPersonaId, taskDefaultPersonaId, workspaceDefaultPersonaId, appDefaultPersonaId, lookupPersona) {
10
20
  const personaId = requestPersonaId ||
11
21
  taskDefaultPersonaId ||
12
22
  workspaceDefaultPersonaId ||
13
- settingsStore.getSetting("default_persona_id") ||
23
+ appDefaultPersonaId ||
14
24
  "";
15
25
  if (!personaId) {
16
26
  throw new Error("No persona configured. Set a default persona at the app, workspace, or task level, or specify one explicitly.");
17
27
  }
18
- const persona = personaStore.getPersona(personaId);
28
+ const persona = lookupPersona(personaId);
19
29
  if (!persona) {
20
30
  throw new Error(`Persona not found: ${personaId}`);
21
31
  }
@@ -37,7 +47,6 @@ export function resolvePersona(requestPersonaId, taskDefaultPersonaId, workspace
37
47
  mcpServers: persona.mcpServers,
38
48
  type: personaType,
39
49
  script: persona.script,
40
- persona,
41
50
  };
42
51
  }
43
52
  //# sourceMappingURL=resolve-persona.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-persona.js","sourceRoot":"","sources":["../src/resolve-persona.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AA2BnE;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,gBAAwB,EACxB,oBAA6B,EAC7B,yBAAkC;IAElC,MAAM,SAAS,GACb,gBAAgB;QAChB,oBAAoB;QACpB,yBAAyB;QACzB,aAAa,CAAC,UAAU,CAAC,oBAAoB,CAAC;QAC9C,EAAE,CAAC;IAEL,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,+GAA+G,CAChH,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACnD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC;IAE5C,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,YAAY,OAAO,CAAC,IAAI,6BAA6B,CAAC,CAAC;IACzE,CAAC;IACD,wEAAwE;IACxE,IAAI,WAAW,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,YAAY,OAAO,CAAC,IAAI,2BAA2B,CAAC,CAAC;IACvE,CAAC;IAED,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,EAAE;QACrB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,IAAI,EAAE,WAAW;QACjB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO;KACR,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"resolve-persona.js","sourceRoot":"","sources":["../src/resolve-persona.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgDH;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAC5B,gBAAwB,EACxB,oBAAwC,EACxC,yBAA6C,EAC7C,mBAAuC,EACvC,aAA8D;IAE9D,MAAM,SAAS,GACb,gBAAgB;QAChB,oBAAoB;QACpB,yBAAyB;QACzB,mBAAmB;QACnB,EAAE,CAAC;IAEL,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,+GAA+G,CAChH,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACzC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC;IAE5C,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,YAAY,OAAO,CAAC,IAAI,6BAA6B,CAAC,CAAC;IACzE,CAAC;IACD,wEAAwE;IACxE,IAAI,WAAW,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,YAAY,OAAO,CAAC,IAAI,2BAA2B,CAAC,CAAC;IACvE,CAAC;IAED,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,EAAE;QACrB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,IAAI,EAAE,WAAW;QACjB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grackle-ai/prompt",
3
- "version": "0.83.1",
3
+ "version": "0.84.0",
4
4
  "description": "System prompt assembly and persona resolution for Grackle agent sessions",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -28,9 +28,7 @@
28
28
  "files": [
29
29
  "dist/"
30
30
  ],
31
- "dependencies": {
32
- "@grackle-ai/database": "0.83.1"
33
- },
31
+ "dependencies": {},
34
32
  "devDependencies": {
35
33
  "@rushstack/heft": "1.2.7",
36
34
  "@types/node": "^22.0.0",