@fragno-dev/pi-harness 0.0.0-stage → 0.0.3

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.
Files changed (140) hide show
  1. package/LICENSE.md +16 -0
  2. package/README.md +181 -2
  3. package/dist/browser/agent-harness-event-protocol-CuKubox1.js +666 -0
  4. package/dist/browser/agent-harness-event-protocol-CuKubox1.js.map +1 -0
  5. package/dist/browser/agent-harness-event-protocol-d6mH_9n3.d.ts +261 -0
  6. package/dist/browser/agent-harness-event-protocol-d6mH_9n3.d.ts.map +1 -0
  7. package/dist/browser/client/clients.d.ts +2 -0
  8. package/dist/browser/client/clients.js +2 -0
  9. package/dist/browser/client/pi-workflow-emission-stream.d.ts +13 -0
  10. package/dist/browser/client/pi-workflow-emission-stream.d.ts.map +1 -0
  11. package/dist/browser/client/pi-workflow-emission-stream.js +29 -0
  12. package/dist/browser/client/pi-workflow-emission-stream.js.map +1 -0
  13. package/dist/browser/client/react.d.ts +147 -0
  14. package/dist/browser/client/react.d.ts.map +1 -0
  15. package/dist/browser/client/react.js +187 -0
  16. package/dist/browser/client/react.js.map +1 -0
  17. package/dist/browser/client/solid.d.ts +150 -0
  18. package/dist/browser/client/solid.d.ts.map +1 -0
  19. package/dist/browser/client/solid.js +130 -0
  20. package/dist/browser/client/solid.js.map +1 -0
  21. package/dist/browser/client/svelte.d.ts +150 -0
  22. package/dist/browser/client/svelte.d.ts.map +1 -0
  23. package/dist/browser/client/svelte.js +132 -0
  24. package/dist/browser/client/svelte.js.map +1 -0
  25. package/dist/browser/client/vanilla.d.ts +177 -0
  26. package/dist/browser/client/vanilla.d.ts.map +1 -0
  27. package/dist/browser/client/vanilla.js +159 -0
  28. package/dist/browser/client/vanilla.js.map +1 -0
  29. package/dist/browser/client/vue.d.ts +150 -0
  30. package/dist/browser/client/vue.d.ts.map +1 -0
  31. package/dist/browser/client/vue.js +128 -0
  32. package/dist/browser/client/vue.js.map +1 -0
  33. package/dist/browser/client/workflow-lofi-session-projection.d.ts +17 -0
  34. package/dist/browser/client/workflow-lofi-session-projection.d.ts.map +1 -0
  35. package/dist/browser/client/workflow-lofi-session-projection.js +107 -0
  36. package/dist/browser/client/workflow-lofi-session-projection.js.map +1 -0
  37. package/dist/browser/clients-DYXj19je.d.ts +247 -0
  38. package/dist/browser/clients-DYXj19je.d.ts.map +1 -0
  39. package/dist/browser/clients-pIAk6ClP.js +1853 -0
  40. package/dist/browser/clients-pIAk6ClP.js.map +1 -0
  41. package/dist/browser/pi/context-usage.d.ts +20 -0
  42. package/dist/browser/pi/context-usage.d.ts.map +1 -0
  43. package/dist/browser/pi/context-usage.js +84 -0
  44. package/dist/browser/pi/context-usage.js.map +1 -0
  45. package/dist/browser/pi/harness/agent-harness-event-protocol.d.ts +2 -0
  46. package/dist/browser/pi/harness/agent-harness-event-protocol.js +2 -0
  47. package/dist/browser/pi/route-schemas.d.ts +2 -0
  48. package/dist/browser/pi/route-schemas.js +130 -0
  49. package/dist/browser/pi/route-schemas.js.map +1 -0
  50. package/dist/browser/pi/workflow-session-projection.d.ts +2 -0
  51. package/dist/browser/pi/workflow-session-projection.js +2 -0
  52. package/dist/browser/route-schemas-DQB5ZR1E.d.ts +109 -0
  53. package/dist/browser/route-schemas-DQB5ZR1E.d.ts.map +1 -0
  54. package/dist/browser/types-8q4RWFXT.js +23 -0
  55. package/dist/browser/types-8q4RWFXT.js.map +1 -0
  56. package/dist/browser/types-Dk856kV1.d.ts +527 -0
  57. package/dist/browser/types-Dk856kV1.d.ts.map +1 -0
  58. package/dist/browser/workflow-session-projection-CJ4MUkpJ.js +443 -0
  59. package/dist/browser/workflow-session-projection-CJ4MUkpJ.js.map +1 -0
  60. package/dist/browser/workflow-session-projection-Dj_a79GF.d.ts +93 -0
  61. package/dist/browser/workflow-session-projection-Dj_a79GF.d.ts.map +1 -0
  62. package/dist/node/pi/compact-command-outcome-projection.js +41 -0
  63. package/dist/node/pi/compact-command-outcome-projection.js.map +1 -0
  64. package/dist/node/pi/context-usage.d.ts +20 -0
  65. package/dist/node/pi/context-usage.d.ts.map +1 -0
  66. package/dist/node/pi/context-usage.js +84 -0
  67. package/dist/node/pi/context-usage.js.map +1 -0
  68. package/dist/node/pi/definition.d.ts +535 -0
  69. package/dist/node/pi/definition.d.ts.map +1 -0
  70. package/dist/node/pi/definition.js +71 -0
  71. package/dist/node/pi/definition.js.map +1 -0
  72. package/dist/node/pi/factory.d.ts +142 -0
  73. package/dist/node/pi/factory.d.ts.map +1 -0
  74. package/dist/node/pi/factory.js +22 -0
  75. package/dist/node/pi/factory.js.map +1 -0
  76. package/dist/node/pi/harness/agent-harness-event-protocol.d.ts +261 -0
  77. package/dist/node/pi/harness/agent-harness-event-protocol.d.ts.map +1 -0
  78. package/dist/node/pi/harness/agent-harness-event-protocol.js +588 -0
  79. package/dist/node/pi/harness/agent-harness-event-protocol.js.map +1 -0
  80. package/dist/node/pi/harness/json-value.js +82 -0
  81. package/dist/node/pi/harness/json-value.js.map +1 -0
  82. package/dist/node/pi/harness/pi-operation-completed.d.ts +16 -0
  83. package/dist/node/pi/harness/pi-operation-completed.d.ts.map +1 -0
  84. package/dist/node/pi/harness/pi-operation-completed.js +71 -0
  85. package/dist/node/pi/harness/pi-operation-completed.js.map +1 -0
  86. package/dist/node/pi/harness/session-storage.d.ts +62 -0
  87. package/dist/node/pi/harness/session-storage.d.ts.map +1 -0
  88. package/dist/node/pi/harness/session-storage.js +174 -0
  89. package/dist/node/pi/harness/session-storage.js.map +1 -0
  90. package/dist/node/pi/pi-jsonl-export.d.ts +11 -0
  91. package/dist/node/pi/pi-jsonl-export.d.ts.map +1 -0
  92. package/dist/node/pi/pi-jsonl-export.js +31 -0
  93. package/dist/node/pi/pi-jsonl-export.js.map +1 -0
  94. package/dist/node/pi/route-schemas.d.ts +109 -0
  95. package/dist/node/pi/route-schemas.d.ts.map +1 -0
  96. package/dist/node/pi/route-schemas.js +130 -0
  97. package/dist/node/pi/route-schemas.js.map +1 -0
  98. package/dist/node/pi/session-command-protocol.d.ts +14 -0
  99. package/dist/node/pi/session-command-protocol.d.ts.map +1 -0
  100. package/dist/node/pi/session-command-protocol.js +25 -0
  101. package/dist/node/pi/session-command-protocol.js.map +1 -0
  102. package/dist/node/pi/session-entry-projection.js +79 -0
  103. package/dist/node/pi/session-entry-projection.js.map +1 -0
  104. package/dist/node/pi/skills.d.ts +70 -0
  105. package/dist/node/pi/skills.d.ts.map +1 -0
  106. package/dist/node/pi/skills.js +150 -0
  107. package/dist/node/pi/skills.js.map +1 -0
  108. package/dist/node/pi/tools.d.ts +12 -0
  109. package/dist/node/pi/tools.d.ts.map +1 -0
  110. package/dist/node/pi/tools.js +8 -0
  111. package/dist/node/pi/tools.js.map +1 -0
  112. package/dist/node/pi/types.d.ts +165 -0
  113. package/dist/node/pi/types.d.ts.map +1 -0
  114. package/dist/node/pi/types.js +49 -0
  115. package/dist/node/pi/types.js.map +1 -0
  116. package/dist/node/pi/wait-for-command-step.js +46 -0
  117. package/dist/node/pi/wait-for-command-step.js.map +1 -0
  118. package/dist/node/pi/workflow-session-live-projection.js +220 -0
  119. package/dist/node/pi/workflow-session-live-projection.js.map +1 -0
  120. package/dist/node/pi/workflow-session-projection.d.ts +84 -0
  121. package/dist/node/pi/workflow-session-projection.d.ts.map +1 -0
  122. package/dist/node/pi/workflow-session-projection.js +100 -0
  123. package/dist/node/pi/workflow-session-projection.js.map +1 -0
  124. package/dist/node/pi/workflows/interactive-chat-workflow.d.ts +37 -0
  125. package/dist/node/pi/workflows/interactive-chat-workflow.d.ts.map +1 -0
  126. package/dist/node/pi/workflows/interactive-chat-workflow.js +219 -0
  127. package/dist/node/pi/workflows/interactive-chat-workflow.js.map +1 -0
  128. package/dist/node/pi/workflows/workflow-agent-harness.d.ts +142 -0
  129. package/dist/node/pi/workflows/workflow-agent-harness.d.ts.map +1 -0
  130. package/dist/node/pi/workflows/workflow-agent-harness.js +450 -0
  131. package/dist/node/pi/workflows/workflow-agent-harness.js.map +1 -0
  132. package/dist/node/routes.d.ts +631 -0
  133. package/dist/node/routes.d.ts.map +1 -0
  134. package/dist/node/routes.js +355 -0
  135. package/dist/node/routes.js.map +1 -0
  136. package/dist/node/schema.d.ts +5 -0
  137. package/dist/node/schema.d.ts.map +1 -0
  138. package/dist/node/schema.js +7 -0
  139. package/dist/node/schema.js.map +1 -0
  140. package/package.json +175 -3
@@ -0,0 +1,31 @@
1
+ import { uuidv7 } from "@earendil-works/pi-agent-core";
2
+ //#region src/pi/pi-jsonl-export.ts
3
+ const PI_JSONL_EXPORT_CWD = "/workspace";
4
+ const leafIdAfterEntry = (entry) => entry.type === "leaf" ? entry.targetId : entry.id;
5
+ async function exportSessionStorageToJsonl(storage, options) {
6
+ const [metadata, entries] = await Promise.all([storage.getMetadata(), storage.getEntries()]);
7
+ const lines = [JSON.stringify({
8
+ type: "session",
9
+ version: 3,
10
+ id: metadata.id,
11
+ timestamp: metadata.createdAt,
12
+ cwd: options.cwd,
13
+ parentSession: options.parentSessionPath
14
+ })];
15
+ for (const entry of entries) lines.push(JSON.stringify(entry));
16
+ const leafId = await storage.getLeafId();
17
+ const last = entries[entries.length - 1];
18
+ const lastLeaf = last ? leafIdAfterEntry(last) : null;
19
+ if (leafId !== lastLeaf) lines.push(JSON.stringify({
20
+ type: "leaf",
21
+ id: uuidv7(),
22
+ parentId: lastLeaf,
23
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
24
+ targetId: leafId
25
+ }));
26
+ return `${lines.join("\n")}\n`;
27
+ }
28
+ //#endregion
29
+ export { PI_JSONL_EXPORT_CWD, exportSessionStorageToJsonl };
30
+
31
+ //# sourceMappingURL=pi-jsonl-export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-jsonl-export.js","names":[],"sources":["../../../src/pi/pi-jsonl-export.ts"],"sourcesContent":["import { uuidv7, type SessionStorage } from \"@earendil-works/pi-agent-core\";\n\nexport const PI_JSONL_EXPORT_CWD = \"/workspace\";\n\nexport type ExportSessionStorageToJsonlOptions = {\n cwd: string;\n parentSessionPath?: string;\n};\n\nconst leafIdAfterEntry = (entry: Awaited<ReturnType<SessionStorage[\"getEntries\"]>>[number]) =>\n entry.type === \"leaf\" ? entry.targetId : entry.id;\n\nexport async function exportSessionStorageToJsonl(\n storage: SessionStorage,\n options: ExportSessionStorageToJsonlOptions,\n): Promise<string> {\n const [metadata, entries] = await Promise.all([storage.getMetadata(), storage.getEntries()]);\n\n const lines: string[] = [\n JSON.stringify({\n type: \"session\",\n version: 3,\n id: metadata.id,\n timestamp: metadata.createdAt,\n cwd: options.cwd,\n parentSession: options.parentSessionPath,\n }),\n ];\n\n for (const entry of entries) {\n lines.push(JSON.stringify(entry));\n }\n\n // Preserve current leaf if the append log does not already end at it.\n const leafId = await storage.getLeafId();\n const last = entries[entries.length - 1];\n const lastLeaf = last ? leafIdAfterEntry(last) : null;\n\n if (leafId !== lastLeaf) {\n lines.push(\n JSON.stringify({\n type: \"leaf\",\n id: uuidv7(),\n parentId: lastLeaf,\n timestamp: new Date().toISOString(),\n targetId: leafId,\n }),\n );\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n"],"mappings":";;AAEA,MAAa,sBAAsB;AAOnC,MAAM,oBAAoB,UACxB,MAAM,SAAS,SAAS,MAAM,WAAW,MAAM;AAEjD,eAAsB,4BACpB,SACA,SACiB;CACjB,MAAM,CAAC,UAAU,WAAW,MAAM,QAAQ,IAAI,CAAC,QAAQ,YAAY,GAAG,QAAQ,WAAW,CAAC,CAAC;CAE3F,MAAM,QAAkB,CACtB,KAAK,UAAU;EACb,MAAM;EACN,SAAS;EACT,IAAI,SAAS;EACb,WAAW,SAAS;EACpB,KAAK,QAAQ;EACb,eAAe,QAAQ;CACzB,CAAC,CACH;CAEA,KAAK,MAAM,SAAS,SAClB,MAAM,KAAK,KAAK,UAAU,KAAK,CAAC;CAIlC,MAAM,SAAS,MAAM,QAAQ,UAAU;CACvC,MAAM,OAAO,QAAQ,QAAQ,SAAS;CACtC,MAAM,WAAW,OAAO,iBAAiB,IAAI,IAAI;CAEjD,IAAI,WAAW,UACb,MAAM,KACJ,KAAK,UAAU;EACb,MAAM;EACN,IAAI,OAAO;EACX,UAAU;EACV,4BAAW,IAAI,KAAK,EAAA,CAAE,YAAY;EAClC,UAAU;CACZ,CAAC,CACH;CAGF,OAAO,GAAG,MAAM,KAAK,IAAI,EAAE;AAC7B"}
@@ -0,0 +1,109 @@
1
+ import { PiHarnessFrontendAgentMessage } from "./harness/agent-harness-event-protocol.js";
2
+ import { PiSessionCommandPayload } from "./types.js";
3
+ import { AgentMessage } from "@earendil-works/pi-agent-core";
4
+ import { z } from "zod";
5
+ //#region src/pi/route-schemas.d.ts
6
+ declare const sessionBaseSchema: z.ZodObject<{
7
+ id: z.ZodString;
8
+ name: z.ZodNullable<z.ZodString>;
9
+ metadata: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
10
+ workflowName: z.ZodString;
11
+ createdAt: z.ZodDate;
12
+ updatedAt: z.ZodDate;
13
+ }, z.core.$strip>;
14
+ declare const agentMessageSchema: z.ZodType<AgentMessage>;
15
+ declare const sessionDetailSchema: z.ZodObject<{
16
+ id: z.ZodString;
17
+ name: z.ZodNullable<z.ZodString>;
18
+ metadata: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
19
+ workflowName: z.ZodString;
20
+ createdAt: z.ZodDate;
21
+ updatedAt: z.ZodDate;
22
+ workflow: z.ZodObject<{
23
+ status: z.ZodEnum<{
24
+ active: "active";
25
+ paused: "paused";
26
+ errored: "errored";
27
+ terminated: "terminated";
28
+ complete: "complete";
29
+ waiting: "waiting";
30
+ }>;
31
+ error: z.ZodOptional<z.ZodObject<{
32
+ name: z.ZodString;
33
+ message: z.ZodString;
34
+ }, z.core.$strip>>;
35
+ output: z.ZodOptional<z.ZodAny>;
36
+ }, z.core.$strip>;
37
+ agent: z.ZodObject<{
38
+ state: z.ZodObject<{
39
+ messages: z.ZodArray<z.ZodType<PiHarnessFrontendAgentMessage, unknown, z.core.$ZodTypeInternals<PiHarnessFrontendAgentMessage, unknown>>>;
40
+ }, z.core.$strip>;
41
+ }, z.core.$strip>;
42
+ }, z.core.$strip>;
43
+ declare const commandInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
44
+ kind: z.ZodLiteral<"prompt">;
45
+ input: z.ZodObject<{
46
+ text: z.ZodString;
47
+ images: z.ZodOptional<z.ZodArray<z.ZodObject<{
48
+ type: z.ZodLiteral<"image">;
49
+ data: z.ZodBase64;
50
+ mimeType: z.ZodString;
51
+ }, z.core.$strip>>>;
52
+ }, z.core.$strip>;
53
+ }, z.core.$strip>, z.ZodObject<{
54
+ kind: z.ZodLiteral<"skill">;
55
+ input: z.ZodObject<{
56
+ name: z.ZodString;
57
+ additionalInstructions: z.ZodOptional<z.ZodString>;
58
+ }, z.core.$strip>;
59
+ }, z.core.$strip>, z.ZodObject<{
60
+ kind: z.ZodLiteral<"promptFromTemplate">;
61
+ input: z.ZodObject<{
62
+ name: z.ZodString;
63
+ args: z.ZodOptional<z.ZodArray<z.ZodString>>;
64
+ }, z.core.$strip>;
65
+ }, z.core.$strip>, z.ZodObject<{
66
+ kind: z.ZodLiteral<"compact">;
67
+ input: z.ZodObject<{
68
+ customInstructions: z.ZodOptional<z.ZodString>;
69
+ }, z.core.$strip>;
70
+ }, z.core.$strip>, z.ZodObject<{
71
+ kind: z.ZodLiteral<"abort">;
72
+ reason: z.ZodOptional<z.ZodString>;
73
+ }, z.core.$strip>, z.ZodObject<{
74
+ kind: z.ZodLiteral<"steer">;
75
+ input: z.ZodObject<{
76
+ text: z.ZodString;
77
+ images: z.ZodOptional<z.ZodArray<z.ZodObject<{
78
+ type: z.ZodLiteral<"image">;
79
+ data: z.ZodBase64;
80
+ mimeType: z.ZodString;
81
+ }, z.core.$strip>>>;
82
+ }, z.core.$strip>;
83
+ }, z.core.$strip>, z.ZodObject<{
84
+ kind: z.ZodLiteral<"followUp">;
85
+ input: z.ZodObject<{
86
+ text: z.ZodString;
87
+ images: z.ZodOptional<z.ZodArray<z.ZodObject<{
88
+ type: z.ZodLiteral<"image">;
89
+ data: z.ZodBase64;
90
+ mimeType: z.ZodString;
91
+ }, z.core.$strip>>>;
92
+ }, z.core.$strip>;
93
+ }, z.core.$strip>], "kind">;
94
+ declare const piSessionCommandPayloadSchema: z.ZodType<PiSessionCommandPayload>;
95
+ declare const commandAckSchema: z.ZodObject<{
96
+ accepted: z.ZodLiteral<true>;
97
+ commandId: z.ZodString;
98
+ status: z.ZodEnum<{
99
+ active: "active";
100
+ paused: "paused";
101
+ errored: "errored";
102
+ terminated: "terminated";
103
+ complete: "complete";
104
+ waiting: "waiting";
105
+ }>;
106
+ }, z.core.$strip>;
107
+ //#endregion
108
+ export { agentMessageSchema, commandAckSchema, commandInputSchema, piSessionCommandPayloadSchema, sessionBaseSchema, sessionDetailSchema };
109
+ //# sourceMappingURL=route-schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-schemas.d.ts","names":[],"sources":["../../../src/pi/route-schemas.ts"],"mappings":";;;;;cAoBM,mBAAiB,EAAA;;;;;;;;cAejB,oBAAoC,EAAE,QAAQ;cAgB9C,qBAAmB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoBnB,oBAAkB,EAAA,uBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAmBlB,+BAA+B,EAAE,QAAQ;cAyBzC,kBAAgB,EAAA"}
@@ -0,0 +1,130 @@
1
+ import { MAX_PI_COMMAND_IMAGE_DATA_LENGTH } from "./types.js";
2
+ import { z } from "zod";
3
+ //#region src/pi/route-schemas.ts
4
+ const workflowStatusValueSchema = z.enum([
5
+ "active",
6
+ "paused",
7
+ "errored",
8
+ "terminated",
9
+ "complete",
10
+ "waiting"
11
+ ]);
12
+ const sessionBaseSchema = z.object({
13
+ id: z.string(),
14
+ name: z.string().nullable(),
15
+ metadata: z.record(z.string(), z.unknown()).nullable(),
16
+ workflowName: z.string(),
17
+ createdAt: z.date(),
18
+ updatedAt: z.date()
19
+ });
20
+ const ImageContentSchema = z.object({
21
+ type: z.literal("image"),
22
+ data: z.base64().min(1),
23
+ mimeType: z.string()
24
+ });
25
+ const agentMessageSchema = z.unknown();
26
+ const workflowStatusSchema = z.object({
27
+ status: workflowStatusValueSchema,
28
+ error: z.object({
29
+ name: z.string(),
30
+ message: z.string()
31
+ }).optional(),
32
+ output: z.any().optional()
33
+ });
34
+ const piAgentStateSnapshotSchema = z.object({ messages: z.array(z.unknown()) });
35
+ const sessionDetailSchema = sessionBaseSchema.extend({
36
+ workflow: workflowStatusSchema,
37
+ agent: z.object({ state: piAgentStateSnapshotSchema })
38
+ });
39
+ const promptInputSchema = z.object({
40
+ text: z.string(),
41
+ images: z.array(ImageContentSchema).refine((images) => images.reduce((totalLength, image) => totalLength + image.data.length, 0) <= MAX_PI_COMMAND_IMAGE_DATA_LENGTH, { message: "Image data exceeds the command persistence limit." }).optional()
42
+ });
43
+ const commandInputSchema = z.discriminatedUnion("kind", [
44
+ z.object({
45
+ kind: z.literal("prompt"),
46
+ input: promptInputSchema
47
+ }),
48
+ z.object({
49
+ kind: z.literal("skill"),
50
+ input: z.object({
51
+ name: z.string(),
52
+ additionalInstructions: z.string().optional()
53
+ })
54
+ }),
55
+ z.object({
56
+ kind: z.literal("promptFromTemplate"),
57
+ input: z.object({
58
+ name: z.string(),
59
+ args: z.array(z.string()).optional()
60
+ })
61
+ }),
62
+ z.object({
63
+ kind: z.literal("compact"),
64
+ input: z.object({ customInstructions: z.string().optional() })
65
+ }),
66
+ z.object({
67
+ kind: z.literal("abort"),
68
+ reason: z.string().optional()
69
+ }),
70
+ z.object({
71
+ kind: z.literal("steer"),
72
+ input: promptInputSchema
73
+ }),
74
+ z.object({
75
+ kind: z.literal("followUp"),
76
+ input: promptInputSchema
77
+ })
78
+ ]);
79
+ const piSessionCommandPayloadSchema = z.discriminatedUnion("kind", [
80
+ z.object({
81
+ commandId: z.string(),
82
+ kind: z.literal("prompt"),
83
+ input: promptInputSchema
84
+ }),
85
+ z.object({
86
+ commandId: z.string(),
87
+ kind: z.literal("skill"),
88
+ input: z.object({
89
+ name: z.string(),
90
+ additionalInstructions: z.string().optional()
91
+ })
92
+ }),
93
+ z.object({
94
+ commandId: z.string(),
95
+ kind: z.literal("promptFromTemplate"),
96
+ input: z.object({
97
+ name: z.string(),
98
+ args: z.array(z.string()).optional()
99
+ })
100
+ }),
101
+ z.object({
102
+ commandId: z.string(),
103
+ kind: z.literal("compact"),
104
+ input: z.object({ customInstructions: z.string().optional() })
105
+ }),
106
+ z.object({
107
+ commandId: z.string(),
108
+ kind: z.literal("abort"),
109
+ reason: z.string().optional()
110
+ }),
111
+ z.object({
112
+ commandId: z.string(),
113
+ kind: z.literal("steer"),
114
+ input: promptInputSchema
115
+ }),
116
+ z.object({
117
+ commandId: z.string(),
118
+ kind: z.literal("followUp"),
119
+ input: promptInputSchema
120
+ })
121
+ ]);
122
+ const commandAckSchema = z.object({
123
+ accepted: z.literal(true),
124
+ commandId: z.string(),
125
+ status: workflowStatusValueSchema
126
+ });
127
+ //#endregion
128
+ export { agentMessageSchema, commandAckSchema, commandInputSchema, piSessionCommandPayloadSchema, sessionBaseSchema, sessionDetailSchema };
129
+
130
+ //# sourceMappingURL=route-schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-schemas.js","names":[],"sources":["../../../src/pi/route-schemas.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport type { AgentMessage } from \"@earendil-works/pi-agent-core\";\n\nimport type { PiHarnessFrontendAgentMessage } from \"./harness/agent-harness-event-protocol\";\nimport {\n MAX_PI_COMMAND_IMAGE_DATA_LENGTH,\n type PiSessionCommandPayload,\n type PiWorkflowStatus,\n} from \"./types\";\n\nconst workflowStatusValueSchema = z.enum([\n \"active\",\n \"paused\",\n \"errored\",\n \"terminated\",\n \"complete\",\n \"waiting\",\n]) satisfies z.ZodType<PiWorkflowStatus>;\n\nconst sessionBaseSchema = z.object({\n id: z.string(),\n name: z.string().nullable(),\n metadata: z.record(z.string(), z.unknown()).nullable(),\n workflowName: z.string(),\n createdAt: z.date(),\n updatedAt: z.date(),\n});\n\nconst ImageContentSchema = z.object({\n type: z.literal(\"image\"),\n data: z.base64().min(1),\n mimeType: z.string(),\n});\n\nconst agentMessageSchema = z.unknown() as z.ZodType<AgentMessage>;\nconst workflowStatusSchema = z.object({\n status: workflowStatusValueSchema,\n error: z\n .object({\n name: z.string(),\n message: z.string(),\n })\n .optional(),\n output: z.any().optional(),\n});\n\nconst piAgentStateSnapshotSchema = z.object({\n messages: z.array(z.unknown() as z.ZodType<PiHarnessFrontendAgentMessage>),\n});\n\nconst sessionDetailSchema = sessionBaseSchema.extend({\n workflow: workflowStatusSchema,\n agent: z.object({\n state: piAgentStateSnapshotSchema,\n }),\n});\n\nconst promptInputSchema = z.object({\n text: z.string(),\n images: z\n .array(ImageContentSchema)\n .refine(\n (images) =>\n images.reduce((totalLength, image) => totalLength + image.data.length, 0) <=\n MAX_PI_COMMAND_IMAGE_DATA_LENGTH,\n { message: \"Image data exceeds the command persistence limit.\" },\n )\n .optional(),\n});\n\nconst commandInputSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"prompt\"), input: promptInputSchema }),\n z.object({\n kind: z.literal(\"skill\"),\n input: z.object({ name: z.string(), additionalInstructions: z.string().optional() }),\n }),\n z.object({\n kind: z.literal(\"promptFromTemplate\"),\n input: z.object({ name: z.string(), args: z.array(z.string()).optional() }),\n }),\n z.object({\n kind: z.literal(\"compact\"),\n input: z.object({ customInstructions: z.string().optional() }),\n }),\n z.object({ kind: z.literal(\"abort\"), reason: z.string().optional() }),\n z.object({ kind: z.literal(\"steer\"), input: promptInputSchema }),\n z.object({ kind: z.literal(\"followUp\"), input: promptInputSchema }),\n]);\n\nconst piSessionCommandPayloadSchema: z.ZodType<PiSessionCommandPayload> = z.discriminatedUnion(\n \"kind\",\n [\n z.object({ commandId: z.string(), kind: z.literal(\"prompt\"), input: promptInputSchema }),\n z.object({\n commandId: z.string(),\n kind: z.literal(\"skill\"),\n input: z.object({ name: z.string(), additionalInstructions: z.string().optional() }),\n }),\n z.object({\n commandId: z.string(),\n kind: z.literal(\"promptFromTemplate\"),\n input: z.object({ name: z.string(), args: z.array(z.string()).optional() }),\n }),\n z.object({\n commandId: z.string(),\n kind: z.literal(\"compact\"),\n input: z.object({ customInstructions: z.string().optional() }),\n }),\n z.object({ commandId: z.string(), kind: z.literal(\"abort\"), reason: z.string().optional() }),\n z.object({ commandId: z.string(), kind: z.literal(\"steer\"), input: promptInputSchema }),\n z.object({ commandId: z.string(), kind: z.literal(\"followUp\"), input: promptInputSchema }),\n ],\n);\n\nconst commandAckSchema = z.object({\n accepted: z.literal(true),\n commandId: z.string(),\n status: workflowStatusValueSchema,\n});\n\nexport {\n agentMessageSchema,\n commandAckSchema,\n commandInputSchema,\n piSessionCommandPayloadSchema,\n sessionBaseSchema,\n sessionDetailSchema,\n};\n"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { PiSessionCommandPayload } from "./types.js";
2
+ //#region src/pi/session-command-protocol.d.ts
3
+ type PiSessionDurableCommand = Extract<PiSessionCommandPayload, {
4
+ kind: "prompt" | "skill" | "promptFromTemplate" | "compact";
5
+ }>;
6
+ type PiSessionActiveCommand = Pick<PiSessionDurableCommand, "commandId" | "kind">;
7
+ /** Identifies the interactive command owning an active workflow step. */
8
+ type PiSessionCommandStartEmission = {
9
+ kind: "pi-session-command-start";
10
+ command: PiSessionActiveCommand;
11
+ };
12
+ //#endregion
13
+ export { PiSessionActiveCommand, PiSessionCommandStartEmission, PiSessionDurableCommand };
14
+ //# sourceMappingURL=session-command-protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-command-protocol.d.ts","names":[],"sources":["../../../src/pi/session-command-protocol.ts"],"mappings":";;KA8BY,0BAA0B,QACpC;EACE;;KAGQ,yBAAyB,KAAK;;KAG9B;EACV;EACA,SAAS"}
@@ -0,0 +1,25 @@
1
+ import { createId } from "@fragno-dev/db/id";
2
+ //#region src/pi/session-command-protocol.ts
3
+ /** Pi command IDs carry their kind so control commands cannot be mistaken for durable operations. */
4
+ function createPiSessionCommandId(kind) {
5
+ return `${kind}_${createId()}`;
6
+ }
7
+ /** Classifies a Pi-issued command ID for the command-step wait route. */
8
+ function piSessionCommandWaitability(commandId) {
9
+ const match = /^([a-zA-Z]+)_[a-zA-Z0-9_-]+$/u.exec(commandId);
10
+ if (!match) return "invalid";
11
+ switch (match[1]) {
12
+ case "prompt":
13
+ case "skill":
14
+ case "promptFromTemplate":
15
+ case "compact": return "waitable";
16
+ case "abort":
17
+ case "steer":
18
+ case "followUp": return "control";
19
+ default: return "invalid";
20
+ }
21
+ }
22
+ //#endregion
23
+ export { createPiSessionCommandId, piSessionCommandWaitability };
24
+
25
+ //# sourceMappingURL=session-command-protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-command-protocol.js","names":[],"sources":["../../../src/pi/session-command-protocol.ts"],"sourcesContent":["import { createId } from \"@fragno-dev/db/id\";\n\nimport type { PiSessionCommandPayload } from \"./types\";\n\n/** Pi command IDs carry their kind so control commands cannot be mistaken for durable operations. */\nexport function createPiSessionCommandId(kind: PiSessionCommandPayload[\"kind\"]): string {\n return `${kind}_${createId()}`;\n}\n\n/** Classifies a Pi-issued command ID for the command-step wait route. */\nexport function piSessionCommandWaitability(commandId: string): \"waitable\" | \"control\" | \"invalid\" {\n const match = /^([a-zA-Z]+)_[a-zA-Z0-9_-]+$/u.exec(commandId);\n if (!match) {\n return \"invalid\";\n }\n switch (match[1]) {\n case \"prompt\":\n case \"skill\":\n case \"promptFromTemplate\":\n case \"compact\":\n return \"waitable\";\n case \"abort\":\n case \"steer\":\n case \"followUp\":\n return \"control\";\n default:\n return \"invalid\";\n }\n}\n\nexport type PiSessionDurableCommand = Extract<\n PiSessionCommandPayload,\n { kind: \"prompt\" | \"skill\" | \"promptFromTemplate\" | \"compact\" }\n>;\n\nexport type PiSessionActiveCommand = Pick<PiSessionDurableCommand, \"commandId\" | \"kind\">;\n\n/** Identifies the interactive command owning an active workflow step. */\nexport type PiSessionCommandStartEmission = {\n kind: \"pi-session-command-start\";\n command: PiSessionActiveCommand;\n};\n"],"mappings":";;;AAKA,SAAgB,yBAAyB,MAA+C;CACtF,OAAO,GAAG,KAAK,GAAG,SAAS;AAC7B;;AAGA,SAAgB,4BAA4B,WAAuD;CACjG,MAAM,QAAQ,gCAAgC,KAAK,SAAS;CAC5D,IAAI,CAAC,OACH,OAAO;CAET,QAAQ,MAAM,IAAd;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,WACH,OAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK,YACH,OAAO;EACT,SACE,OAAO;CACX;AACF"}
@@ -0,0 +1,79 @@
1
+ import { PiSessionDataIntegrityError } from "./types.js";
2
+ import { buildSessionContext } from "@earendil-works/pi-agent-core";
3
+ //#region src/pi/session-entry-projection.ts
4
+ const dataIntegrityError = (identity, message, cause) => new PiSessionDataIntegrityError(identity.workflowName, identity.sessionId, new Error(message, cause === void 0 ? void 0 : { cause }));
5
+ /**
6
+ * Workflow history exposes step results as `unknown`, but harness-run results are written by
7
+ * `withWorkflowAgentHarness`. This is the single trust boundary for that internally owned data.
8
+ */
9
+ const asPersistedPiHarnessStepResult = (value) => {
10
+ const result = value;
11
+ return result?.type === "harness-run" ? result : null;
12
+ };
13
+ const mergePiSessionEntries = (...entryGroups) => {
14
+ const entries = [];
15
+ const indexes = /* @__PURE__ */ new Map();
16
+ for (const entryGroup of entryGroups) for (const entry of entryGroup) {
17
+ const index = indexes.get(entry.id);
18
+ if (index === void 0) {
19
+ indexes.set(entry.id, entries.length);
20
+ entries.push(entry);
21
+ } else entries[index] = entry;
22
+ }
23
+ return entries;
24
+ };
25
+ const latestCompletedPiHarnessEntries = (steps) => mergePiSessionEntries(...steps.flatMap((step) => {
26
+ if (step.status !== "completed") return [];
27
+ const result = asPersistedPiHarnessStepResult(step.result);
28
+ return result ? [result.appendedEntries] : [];
29
+ }));
30
+ const resolveActiveSessionPath = (entries, identity) => {
31
+ let leafId = null;
32
+ for (const entry of entries) leafId = entry.type === "leaf" ? entry.targetId : entry.id;
33
+ if (leafId === null) return [];
34
+ const entriesById = /* @__PURE__ */ new Map();
35
+ for (const entry of entries) {
36
+ if (entriesById.has(entry.id)) throw dataIntegrityError(identity, `Pi session tree contains duplicate entry ${entry.id}.`);
37
+ entriesById.set(entry.id, entry);
38
+ }
39
+ const reversePath = [];
40
+ const visitedEntryIds = /* @__PURE__ */ new Set();
41
+ let currentId = leafId;
42
+ while (currentId !== null) {
43
+ if (visitedEntryIds.has(currentId)) throw dataIntegrityError(identity, `Pi session tree contains a parent cycle at ${currentId}.`);
44
+ visitedEntryIds.add(currentId);
45
+ const entry = entriesById.get(currentId);
46
+ if (!entry) throw dataIntegrityError(identity, `Pi session tree references missing entry ${currentId}.`);
47
+ reversePath.push(entry);
48
+ currentId = entry.parentId;
49
+ }
50
+ return reversePath.reverse();
51
+ };
52
+ const projectPiSessionEntries = (entries, identity, options = {}) => {
53
+ const activePath = resolveActiveSessionPath(entries, identity);
54
+ let contextMessages;
55
+ try {
56
+ contextMessages = buildSessionContext(activePath).messages;
57
+ } catch (error) {
58
+ throw dataIntegrityError(identity, "Pi session entries cannot build a valid context.", error);
59
+ }
60
+ const timelineMessages = [...options.timelineMessagesAfterEntryId?.get(null) ?? []];
61
+ for (const entry of activePath) {
62
+ if (entry.type === "message") timelineMessages.push(entry.message);
63
+ else if (entry.type === "compaction") timelineMessages.push({
64
+ role: "compactionSummary",
65
+ summary: entry.summary,
66
+ tokensBefore: entry.tokensBefore,
67
+ timestamp: new Date(entry.timestamp).getTime()
68
+ });
69
+ timelineMessages.push(...options.timelineMessagesAfterEntryId?.get(entry.id) ?? []);
70
+ }
71
+ return {
72
+ contextMessages,
73
+ timelineMessages
74
+ };
75
+ };
76
+ //#endregion
77
+ export { asPersistedPiHarnessStepResult, latestCompletedPiHarnessEntries, mergePiSessionEntries, projectPiSessionEntries };
78
+
79
+ //# sourceMappingURL=session-entry-projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-entry-projection.js","names":[],"sources":["../../../src/pi/session-entry-projection.ts"],"sourcesContent":["import {\n buildSessionContext,\n type AgentMessage,\n type SessionTreeEntry,\n} from \"@earendil-works/pi-agent-core\";\n\nimport type { PiHarnessFrontendAgentMessage } from \"./harness/agent-harness-event-protocol\";\nimport { PiSessionDataIntegrityError } from \"./types\";\nimport type { PiHarnessStepResult } from \"./workflows/workflow-agent-harness\";\n\nexport type PiProjectionSessionIdentity = {\n workflowName: string;\n sessionId: string;\n};\n\nexport type PersistedPiHarnessStepResult = PiHarnessStepResult & {\n outcome?: \"completed\" | \"aborted\";\n value?: unknown;\n};\n\nconst dataIntegrityError = (\n identity: PiProjectionSessionIdentity,\n message: string,\n cause?: unknown,\n): PiSessionDataIntegrityError =>\n new PiSessionDataIntegrityError(\n identity.workflowName,\n identity.sessionId,\n new Error(message, cause === undefined ? undefined : { cause }),\n );\n\n/**\n * Workflow history exposes step results as `unknown`, but harness-run results are written by\n * `withWorkflowAgentHarness`. This is the single trust boundary for that internally owned data.\n */\nexport const asPersistedPiHarnessStepResult = (\n value: unknown,\n): PersistedPiHarnessStepResult | null => {\n const result = value as PersistedPiHarnessStepResult | undefined;\n return result?.type === \"harness-run\" ? result : null;\n};\n\nexport const mergePiSessionEntries = (\n ...entryGroups: readonly (readonly SessionTreeEntry[])[]\n): SessionTreeEntry[] => {\n const entries: SessionTreeEntry[] = [];\n const indexes = new Map<string, number>();\n\n for (const entryGroup of entryGroups) {\n for (const entry of entryGroup) {\n const index = indexes.get(entry.id);\n if (index === undefined) {\n indexes.set(entry.id, entries.length);\n entries.push(entry);\n } else {\n entries[index] = entry;\n }\n }\n }\n\n return entries;\n};\n\nexport const latestCompletedPiHarnessEntries = (\n steps: readonly { status: string; result: unknown }[],\n): SessionTreeEntry[] =>\n mergePiSessionEntries(\n ...steps.flatMap((step) => {\n if (step.status !== \"completed\") {\n return [];\n }\n const result = asPersistedPiHarnessStepResult(step.result);\n return result ? [result.appendedEntries] : [];\n }),\n );\n\nconst resolveActiveSessionPath = (\n entries: readonly SessionTreeEntry[],\n identity: PiProjectionSessionIdentity,\n): SessionTreeEntry[] => {\n let leafId: string | null = null;\n for (const entry of entries) {\n leafId = entry.type === \"leaf\" ? entry.targetId : entry.id;\n }\n if (leafId === null) {\n return [];\n }\n\n const entriesById = new Map<string, SessionTreeEntry>();\n for (const entry of entries) {\n if (entriesById.has(entry.id)) {\n throw dataIntegrityError(identity, `Pi session tree contains duplicate entry ${entry.id}.`);\n }\n entriesById.set(entry.id, entry);\n }\n const reversePath: SessionTreeEntry[] = [];\n const visitedEntryIds = new Set<string>();\n let currentId: string | null = leafId;\n\n while (currentId !== null) {\n if (visitedEntryIds.has(currentId)) {\n throw dataIntegrityError(\n identity,\n `Pi session tree contains a parent cycle at ${currentId}.`,\n );\n }\n visitedEntryIds.add(currentId);\n\n const entry = entriesById.get(currentId);\n if (!entry) {\n throw dataIntegrityError(identity, `Pi session tree references missing entry ${currentId}.`);\n }\n reversePath.push(entry);\n currentId = entry.parentId;\n }\n\n return reversePath.reverse();\n};\n\nexport type ProjectedPiSessionEntries = {\n contextMessages: AgentMessage[];\n timelineMessages: PiHarnessFrontendAgentMessage[];\n};\n\nexport type ProjectPiSessionEntriesOptions = {\n timelineMessagesAfterEntryId?: ReadonlyMap<\n string | null,\n readonly PiHarnessFrontendAgentMessage[]\n >;\n};\n\nexport const projectPiSessionEntries = (\n entries: readonly SessionTreeEntry[],\n identity: PiProjectionSessionIdentity,\n options: ProjectPiSessionEntriesOptions = {},\n): ProjectedPiSessionEntries => {\n const activePath = resolveActiveSessionPath(entries, identity);\n\n let contextMessages: AgentMessage[];\n try {\n contextMessages = buildSessionContext(activePath).messages;\n } catch (error) {\n throw dataIntegrityError(identity, \"Pi session entries cannot build a valid context.\", error);\n }\n\n const timelineMessages: PiHarnessFrontendAgentMessage[] = [\n ...(options.timelineMessagesAfterEntryId?.get(null) ?? []),\n ];\n for (const entry of activePath) {\n if (entry.type === \"message\") {\n timelineMessages.push(entry.message);\n } else if (entry.type === \"compaction\") {\n timelineMessages.push({\n role: \"compactionSummary\",\n summary: entry.summary,\n tokensBefore: entry.tokensBefore,\n timestamp: new Date(entry.timestamp).getTime(),\n });\n }\n timelineMessages.push(...(options.timelineMessagesAfterEntryId?.get(entry.id) ?? []));\n }\n\n return { contextMessages, timelineMessages };\n};\n"],"mappings":";;;AAoBA,MAAM,sBACJ,UACA,SACA,UAEA,IAAI,4BACF,SAAS,cACT,SAAS,WACT,IAAI,MAAM,SAAS,UAAU,KAAA,IAAY,KAAA,IAAY,EAAE,MAAM,CAAC,CAChE;;;;;AAMF,MAAa,kCACX,UACwC;CACxC,MAAM,SAAS;CACf,OAAO,QAAQ,SAAS,gBAAgB,SAAS;AACnD;AAEA,MAAa,yBACX,GAAG,gBACoB;CACvB,MAAM,UAA8B,CAAC;CACrC,MAAM,0BAAU,IAAI,IAAoB;CAExC,KAAK,MAAM,cAAc,aACvB,KAAK,MAAM,SAAS,YAAY;EAC9B,MAAM,QAAQ,QAAQ,IAAI,MAAM,EAAE;EAClC,IAAI,UAAU,KAAA,GAAW;GACvB,QAAQ,IAAI,MAAM,IAAI,QAAQ,MAAM;GACpC,QAAQ,KAAK,KAAK;EACpB,OACE,QAAQ,SAAS;CAErB;CAGF,OAAO;AACT;AAEA,MAAa,mCACX,UAEA,sBACE,GAAG,MAAM,SAAS,SAAS;CACzB,IAAI,KAAK,WAAW,aAClB,OAAO,CAAC;CAEV,MAAM,SAAS,+BAA+B,KAAK,MAAM;CACzD,OAAO,SAAS,CAAC,OAAO,eAAe,IAAI,CAAC;AAC9C,CAAC,CACH;AAEF,MAAM,4BACJ,SACA,aACuB;CACvB,IAAI,SAAwB;CAC5B,KAAK,MAAM,SAAS,SAClB,SAAS,MAAM,SAAS,SAAS,MAAM,WAAW,MAAM;CAE1D,IAAI,WAAW,MACb,OAAO,CAAC;CAGV,MAAM,8BAAc,IAAI,IAA8B;CACtD,KAAK,MAAM,SAAS,SAAS;EAC3B,IAAI,YAAY,IAAI,MAAM,EAAE,GAC1B,MAAM,mBAAmB,UAAU,4CAA4C,MAAM,GAAG,EAAE;EAE5F,YAAY,IAAI,MAAM,IAAI,KAAK;CACjC;CACA,MAAM,cAAkC,CAAC;CACzC,MAAM,kCAAkB,IAAI,IAAY;CACxC,IAAI,YAA2B;CAE/B,OAAO,cAAc,MAAM;EACzB,IAAI,gBAAgB,IAAI,SAAS,GAC/B,MAAM,mBACJ,UACA,8CAA8C,UAAU,EAC1D;EAEF,gBAAgB,IAAI,SAAS;EAE7B,MAAM,QAAQ,YAAY,IAAI,SAAS;EACvC,IAAI,CAAC,OACH,MAAM,mBAAmB,UAAU,4CAA4C,UAAU,EAAE;EAE7F,YAAY,KAAK,KAAK;EACtB,YAAY,MAAM;CACpB;CAEA,OAAO,YAAY,QAAQ;AAC7B;AAcA,MAAa,2BACX,SACA,UACA,UAA0C,CAAC,MACb;CAC9B,MAAM,aAAa,yBAAyB,SAAS,QAAQ;CAE7D,IAAI;CACJ,IAAI;EACF,kBAAkB,oBAAoB,UAAU,CAAC,CAAC;CACpD,SAAS,OAAO;EACd,MAAM,mBAAmB,UAAU,oDAAoD,KAAK;CAC9F;CAEA,MAAM,mBAAoD,CACxD,GAAI,QAAQ,8BAA8B,IAAI,IAAI,KAAK,CAAC,CAC1D;CACA,KAAK,MAAM,SAAS,YAAY;EAC9B,IAAI,MAAM,SAAS,WACjB,iBAAiB,KAAK,MAAM,OAAO;OAC9B,IAAI,MAAM,SAAS,cACxB,iBAAiB,KAAK;GACpB,MAAM;GACN,SAAS,MAAM;GACf,cAAc,MAAM;GACpB,WAAW,IAAI,KAAK,MAAM,SAAS,CAAC,CAAC,QAAQ;EAC/C,CAAC;EAEH,iBAAiB,KAAK,GAAI,QAAQ,8BAA8B,IAAI,MAAM,EAAE,KAAK,CAAC,CAAE;CACtF;CAEA,OAAO;EAAE;EAAiB;CAAiB;AAC7C"}
@@ -0,0 +1,70 @@
1
+ import { PiToolDefinition } from "./types.js";
2
+ import { Type } from "typebox";
3
+ //#region src/pi/skills.d.ts
4
+ type PiSkillResource = {
5
+ path: string;
6
+ description?: string;
7
+ content?: string;
8
+ mimeType?: string;
9
+ metadata?: Record<string, unknown>;
10
+ };
11
+ type PiSkillDefinition = {
12
+ name: string;
13
+ description: string;
14
+ body?: string;
15
+ location?: string;
16
+ directory?: string;
17
+ resources?: readonly PiSkillResource[];
18
+ metadata?: Record<string, unknown>;
19
+ };
20
+ type PiSkillDefinitionInput = Omit<PiSkillDefinition, "name"> & {
21
+ name?: string;
22
+ };
23
+ type PiSkillRegistry = Record<string, PiSkillDefinition>;
24
+ type PiAgentSkillSelection = readonly string[] | "all";
25
+ type PiSkillResolverContext = {
26
+ workflowName: string;
27
+ sessionId: string;
28
+ turnId: string;
29
+ };
30
+ type PiSkillRegistryResolver = (context: PiSkillResolverContext) => PiSkillRegistry | Promise<PiSkillRegistry>;
31
+ type PiSkillRegistrySource = PiSkillRegistry | PiSkillRegistryResolver;
32
+ type PiSkillCatalogXmlInput = PiSkillRegistry | readonly PiSkillDefinition[];
33
+ type PiSkillActivationDetails = {
34
+ found: true;
35
+ name: string;
36
+ resourceCount: number;
37
+ } | {
38
+ found: false;
39
+ name: string;
40
+ };
41
+ type CreatePiSkillActivationToolOptions = {
42
+ name?: string;
43
+ label?: string;
44
+ description?: string;
45
+ };
46
+ type PiSkillInvocationContextOptions = {
47
+ extraUserInstructions?: string;
48
+ };
49
+ declare const renderPiSkillCatalogXml: (skills: PiSkillCatalogXmlInput) => string;
50
+ declare const renderPiSkillInvocationContext: (skill: PiSkillDefinition, options?: PiSkillInvocationContextOptions) => string;
51
+ declare const skillActivationParameters: Type.TObject<{
52
+ name: Type.TString;
53
+ }>;
54
+ declare const createPiSkillActivationTool: (skills: PiSkillCatalogXmlInput, options?: CreatePiSkillActivationToolOptions) => PiToolDefinition<typeof skillActivationParameters, PiSkillActivationDetails>;
55
+ declare class PiSkillDefinitionBuilder<TName extends string = string> {
56
+ #private;
57
+ constructor(name: TName);
58
+ description(description: string): this;
59
+ body(body: string): this;
60
+ location(location: string): this;
61
+ directory(directory: string): this;
62
+ resource(path: string, resource?: Omit<PiSkillResource, "path">): this;
63
+ resources(resources: readonly PiSkillResource[]): this;
64
+ metadata(metadata: Record<string, unknown>): this;
65
+ metadataValue(key: string, value: unknown): this;
66
+ build(): PiSkillDefinition;
67
+ }
68
+ //#endregion
69
+ export { CreatePiSkillActivationToolOptions, PiAgentSkillSelection, PiSkillActivationDetails, PiSkillCatalogXmlInput, PiSkillDefinition, PiSkillDefinitionBuilder, PiSkillDefinitionInput, PiSkillInvocationContextOptions, PiSkillRegistry, PiSkillRegistryResolver, PiSkillRegistrySource, PiSkillResolverContext, PiSkillResource, createPiSkillActivationTool, renderPiSkillCatalogXml, renderPiSkillInvocationContext };
70
+ //# sourceMappingURL=skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.d.ts","names":[],"sources":["../../../src/pi/skills.ts"],"mappings":";;;KAIY;EACV;EACA;EACA;EACA;EACA,WAAW;;KAGD;EACV;EACA;EACA;EACA;EACA;EACA,qBAAqB;EACrB,WAAW;;KAGD,yBAAyB,KAAK;EACxC;;KAGU,kBAAkB,eAAe;KAEjC;KAEA;EACV;EACA;EACA;;KAGU,2BACV,SAAS,2BACN,kBAAkB,QAAQ;KAEnB,wBAAwB,kBAAkB;KAE1C,yBAAyB,2BAA2B;KAEpD;EAEN;EACA;EACA;;EAGA;EACA;;KAGM;EACV;EACA;EACA;;KAGU;EACV;;cAoBW,0BAA2B,QAAQ;cAqEnC,iCACX,OAAO,mBACP,UAAS;cAiBL,2BAAyB,KAAA;QAAzB,KAAA;;cAEO,8BACX,QAAQ,wBACR,UAAS,uCACR,wBAAwB,2BAA2B;cA2BzC,yBAAyB;;cASxB,MAAM;EAIlB,YAAY;EAKZ,KAAK;EAKL,SAAS;EAKT,UAAU;EAKV,SAAS,cAAc,WAAU,KAAK;EAKtC,UAAU,oBAAoB;EAK9B,SAAS,UAAU;EAKnB,cAAc,aAAa;EAK3B,SAAS"}