coaiajs 0.1.0 → 0.1.2

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 (187) hide show
  1. package/README.md +7 -3
  2. package/dist/mcp/config.d.ts +4 -0
  3. package/dist/mcp/config.d.ts.map +1 -0
  4. package/dist/mcp/config.js +52 -26
  5. package/dist/mcp/config.js.map +1 -0
  6. package/dist/mcp/prompts.d.ts +19 -0
  7. package/dist/mcp/prompts.d.ts.map +1 -0
  8. package/dist/mcp/prompts.js +111 -0
  9. package/dist/mcp/prompts.js.map +1 -0
  10. package/dist/mcp/resources.d.ts +5 -0
  11. package/dist/mcp/resources.d.ts.map +1 -0
  12. package/dist/mcp/resources.js +77 -0
  13. package/dist/mcp/resources.js.map +1 -0
  14. package/dist/mcp/server.d.ts.map +1 -0
  15. package/dist/mcp/server.js +167 -75
  16. package/dist/mcp/server.js.map +1 -0
  17. package/dist/mcp/tools/coaiapy-tools.d.ts.map +1 -0
  18. package/dist/mcp/tools/coaiapy-tools.js +1 -0
  19. package/dist/mcp/tools/coaiapy-tools.js.map +1 -0
  20. package/dist/mcp/tools/index.d.ts.map +1 -0
  21. package/dist/mcp/tools/index.js.map +1 -0
  22. package/dist/src/audio.d.ts.map +1 -0
  23. package/dist/src/audio.js.map +1 -0
  24. package/dist/src/cli-helpers.d.ts.map +1 -0
  25. package/dist/src/cli-helpers.js.map +1 -0
  26. package/dist/src/cli.d.ts.map +1 -0
  27. package/dist/src/cli.js +4 -4
  28. package/dist/src/cli.js.map +1 -0
  29. package/dist/src/config.d.ts +2 -0
  30. package/dist/src/config.d.ts.map +1 -0
  31. package/dist/src/config.js +44 -14
  32. package/dist/src/config.js.map +1 -0
  33. package/dist/src/environment.d.ts.map +1 -0
  34. package/dist/src/environment.js.map +1 -0
  35. package/dist/src/github.d.ts.map +1 -0
  36. package/dist/src/github.js.map +1 -0
  37. package/dist/src/index.d.ts +13 -0
  38. package/dist/src/index.d.ts.map +1 -0
  39. package/dist/src/index.js +13 -0
  40. package/dist/src/index.js.map +1 -0
  41. package/dist/src/langfuse/client.d.ts.map +1 -0
  42. package/dist/src/langfuse/client.js.map +1 -0
  43. package/dist/src/langfuse/comments.d.ts.map +1 -0
  44. package/dist/src/langfuse/comments.js.map +1 -0
  45. package/dist/src/langfuse/datasets.d.ts.map +1 -0
  46. package/dist/src/langfuse/datasets.js.map +1 -0
  47. package/dist/src/langfuse/index.d.ts.map +1 -0
  48. package/dist/src/langfuse/index.js.map +1 -0
  49. package/dist/src/langfuse/media.d.ts.map +1 -0
  50. package/dist/src/langfuse/media.js.map +1 -0
  51. package/dist/src/langfuse/observations.d.ts.map +1 -0
  52. package/dist/src/langfuse/observations.js.map +1 -0
  53. package/dist/src/langfuse/prompts.d.ts.map +1 -0
  54. package/dist/src/langfuse/prompts.js.map +1 -0
  55. package/dist/src/langfuse/scores.d.ts.map +1 -0
  56. package/dist/src/langfuse/scores.js.map +1 -0
  57. package/dist/src/langfuse/traces.d.ts.map +1 -0
  58. package/dist/src/langfuse/traces.js.map +1 -0
  59. package/dist/src/llm.d.ts.map +1 -0
  60. package/dist/src/llm.js.map +1 -0
  61. package/dist/src/narrative/graph-manager.d.ts.map +1 -0
  62. package/dist/src/narrative/graph-manager.js.map +1 -0
  63. package/dist/src/narrative/index.d.ts +32 -1
  64. package/dist/src/narrative/index.d.ts.map +1 -0
  65. package/dist/src/narrative/index.js +97 -1
  66. package/dist/src/narrative/index.js.map +1 -0
  67. package/dist/src/narrative/markdown-export.d.ts.map +1 -0
  68. package/dist/src/narrative/markdown-export.js.map +1 -0
  69. package/dist/src/narrative/tool-definitions.d.ts.map +1 -0
  70. package/dist/src/narrative/tool-definitions.js.map +1 -0
  71. package/dist/src/narrative/tool-handlers.d.ts.map +1 -0
  72. package/dist/src/narrative/tool-handlers.js.map +1 -0
  73. package/dist/src/narrative/types.d.ts.map +1 -0
  74. package/dist/src/narrative/types.js.map +1 -0
  75. package/dist/src/narrative/validation.d.ts.map +1 -0
  76. package/dist/src/narrative/validation.js.map +1 -0
  77. package/dist/src/pde/index.d.ts +4 -0
  78. package/dist/src/pde/index.d.ts.map +1 -0
  79. package/dist/src/pde/index.js +19 -0
  80. package/dist/src/pde/index.js.map +1 -0
  81. package/dist/src/pde/mcp-handlers.d.ts.map +1 -0
  82. package/dist/src/pde/mcp-handlers.js.map +1 -0
  83. package/dist/src/pde/mcp-tools.d.ts.map +1 -0
  84. package/dist/src/pde/mcp-tools.js.map +1 -0
  85. package/dist/src/pde/session-manager.d.ts.map +1 -0
  86. package/dist/src/pde/session-manager.js.map +1 -0
  87. package/dist/src/pde/stc-mapper.d.ts.map +1 -0
  88. package/dist/src/pde/stc-mapper.js.map +1 -0
  89. package/dist/src/pipeline/index.d.ts.map +1 -0
  90. package/dist/src/pipeline/index.js.map +1 -0
  91. package/dist/src/pipeline/template-engine.d.ts.map +1 -0
  92. package/dist/src/pipeline/template-engine.js.map +1 -0
  93. package/dist/src/planning/index.d.ts +3 -0
  94. package/dist/src/planning/index.d.ts.map +1 -0
  95. package/dist/src/planning/index.js +13 -0
  96. package/dist/src/planning/index.js.map +1 -0
  97. package/dist/src/planning/mcp-handlers.d.ts.map +1 -0
  98. package/dist/src/planning/mcp-handlers.js.map +1 -0
  99. package/dist/src/planning/mcp-tools.d.ts.map +1 -0
  100. package/dist/src/planning/mcp-tools.js.map +1 -0
  101. package/dist/src/planning/plan-parser.d.ts.map +1 -0
  102. package/dist/src/planning/plan-parser.js.map +1 -0
  103. package/dist/src/redis.d.ts.map +1 -0
  104. package/dist/src/redis.js +20 -8
  105. package/dist/src/redis.js.map +1 -0
  106. package/dist/src/types.d.ts +1 -0
  107. package/dist/src/types.d.ts.map +1 -0
  108. package/dist/src/types.js.map +1 -0
  109. package/package.json +67 -2
  110. package/rispecs/00-coaiajs-platform.spec.md +23 -10
  111. package/rispecs/01-core-config.spec.md +7 -37
  112. package/rispecs/02-redis-module.spec.md +2 -1
  113. package/rispecs/03-langfuse-module.spec.md +7 -5
  114. package/rispecs/04-narrative-engine.spec.md +9 -9
  115. package/rispecs/05-pde-engine.spec.md +23 -23
  116. package/rispecs/06-planning-engine.spec.md +14 -13
  117. package/rispecs/07-pipeline-templates.spec.md +7 -7
  118. package/rispecs/08-cli-interface.spec.md +13 -25
  119. package/rispecs/09-mcp-server.spec.md +57 -62
  120. package/rispecs/10-audio-module.spec.md +3 -3
  121. package/rispecs/KINSHIP.md +4 -4
  122. package/rispecs/README.md +33 -7
  123. package/articles/academic/creative-orientation-vs-problem-solving.md +0 -177
  124. package/articles/academic/jsonl-knowledge-graphs-agent-memory.md +0 -142
  125. package/articles/academic/langfuse-observability-llm-pipelines.md +0 -144
  126. package/articles/academic/medicine-wheel-software-architecture.md +0 -163
  127. package/articles/academic/mmot-autonomous-agents.md +0 -156
  128. package/articles/academic/model-context-protocol-interagent.md +0 -161
  129. package/articles/academic/pde-prompt-decomposition.md +0 -186
  130. package/articles/academic/structural-tension-in-ai-agents.md +0 -134
  131. package/articles/reviews/mcp-protocol-design-review.md +0 -170
  132. package/articles/reviews/observability-ai-systems-review.md +0 -176
  133. package/articles/reviews/prompt-engineering-decomposition-review.md +0 -184
  134. package/articles/surveys/agent-orchestration-survey.md +0 -186
  135. package/articles/surveys/knowledge-graph-storage-survey.md +0 -204
  136. package/articles/surveys/structural-tension-methodology-survey.md +0 -154
  137. package/articles/technical/aws-sdk-v3-polly.md +0 -270
  138. package/articles/technical/commander-cli-framework.md +0 -262
  139. package/articles/technical/dotenv-config-patterns.md +0 -360
  140. package/articles/technical/ioredis-vs-redis.md +0 -142
  141. package/articles/technical/langfuse-js-sdk-vs-rest.md +0 -191
  142. package/articles/technical/mcp-sdk-typescript.md +0 -291
  143. package/articles/technical/octokit-github-api.md +0 -293
  144. package/articles/technical/openai-sdk-modern.md +0 -231
  145. package/articles/technical/yaml-parsing-node.md +0 -266
  146. package/articles/technical/zod-runtime-validation.md +0 -212
  147. package/mcp/config.ts +0 -196
  148. package/mcp/server.ts +0 -402
  149. package/mcp/tools/coaiapy-tools.ts +0 -364
  150. package/mcp/tools/index.ts +0 -4
  151. package/src/audio.ts +0 -76
  152. package/src/cli-helpers.ts +0 -86
  153. package/src/cli.ts +0 -1223
  154. package/src/config.ts +0 -172
  155. package/src/environment.ts +0 -171
  156. package/src/github.ts +0 -143
  157. package/src/langfuse/client.ts +0 -105
  158. package/src/langfuse/comments.ts +0 -52
  159. package/src/langfuse/datasets.ts +0 -178
  160. package/src/langfuse/index.ts +0 -33
  161. package/src/langfuse/media.ts +0 -193
  162. package/src/langfuse/observations.ts +0 -131
  163. package/src/langfuse/prompts.ts +0 -157
  164. package/src/langfuse/scores.ts +0 -456
  165. package/src/langfuse/traces.ts +0 -276
  166. package/src/llm.ts +0 -106
  167. package/src/narrative/graph-manager.ts +0 -1358
  168. package/src/narrative/index.ts +0 -32
  169. package/src/narrative/markdown-export.ts +0 -535
  170. package/src/narrative/tool-definitions.ts +0 -635
  171. package/src/narrative/tool-handlers.ts +0 -528
  172. package/src/narrative/types.ts +0 -9
  173. package/src/narrative/validation.ts +0 -179
  174. package/src/pde/index.ts +0 -8
  175. package/src/pde/mcp-handlers.ts +0 -359
  176. package/src/pde/mcp-tools.ts +0 -201
  177. package/src/pde/session-manager.ts +0 -248
  178. package/src/pde/stc-mapper.ts +0 -298
  179. package/src/pipeline/index.ts +0 -7
  180. package/src/pipeline/template-engine.ts +0 -398
  181. package/src/planning/index.ts +0 -13
  182. package/src/planning/mcp-handlers.ts +0 -369
  183. package/src/planning/mcp-tools.ts +0 -155
  184. package/src/planning/plan-parser.ts +0 -587
  185. package/src/redis.ts +0 -97
  186. package/src/types.ts +0 -280
  187. package/tsconfig.json +0 -26
@@ -1,179 +0,0 @@
1
- // Strict input validation for multi-LLM compatibility (no zod dependency)
2
- type ValidationType = 'string' | 'number' | 'boolean' | 'array' | 'object' | 'date' | 'enum';
3
-
4
- interface ValidationRule {
5
- type: ValidationType;
6
- required?: boolean;
7
- minLength?: number;
8
- maxLength?: number;
9
- pattern?: RegExp;
10
- minValue?: number;
11
- maxValue?: number;
12
- enumValues?: (string | number)[];
13
- items?: ValidationRule;
14
- properties?: Record<string, ValidationRule>;
15
- }
16
-
17
- interface ValidationSchema {
18
- [key: string]: ValidationRule;
19
- }
20
-
21
- export function validate(args: unknown, schema: ValidationSchema): { valid: boolean; error?: string } {
22
- if (typeof args !== 'object' || args === null) {
23
- return { valid: false, error: 'Arguments must be an object' };
24
- }
25
-
26
- const record = args as Record<string, unknown>;
27
-
28
- for (const [key, rule] of Object.entries(schema)) {
29
- const value = record[key];
30
-
31
- if (rule.required && (value === undefined || value === null)) {
32
- return { valid: false, error: `Missing required field: ${key}` };
33
- }
34
-
35
- if (value === undefined || value === null) continue;
36
-
37
- const result = validateValue(value, rule, key);
38
- if (!result.valid) return result;
39
- }
40
-
41
- return { valid: true };
42
- }
43
-
44
- function validateValue(value: unknown, rule: ValidationRule, path: string): { valid: boolean; error?: string } {
45
- switch (rule.type) {
46
- case 'string':
47
- if (typeof value !== 'string') {
48
- return { valid: false, error: `${path} must be a string, got ${typeof value}` };
49
- }
50
- if (rule.minLength && value.length < rule.minLength) {
51
- return { valid: false, error: `${path} must be at least ${rule.minLength} characters` };
52
- }
53
- if (rule.maxLength && value.length > rule.maxLength) {
54
- return { valid: false, error: `${path} must be at most ${rule.maxLength} characters` };
55
- }
56
- if (rule.pattern && !rule.pattern.test(value)) {
57
- return { valid: false, error: `${path} format is invalid` };
58
- }
59
- if (rule.enumValues && !rule.enumValues.includes(value)) {
60
- return { valid: false, error: `${path} must be one of: ${rule.enumValues.join(', ')}` };
61
- }
62
- break;
63
-
64
- case 'number':
65
- if (typeof value !== 'number' || isNaN(value)) {
66
- return { valid: false, error: `${path} must be a number` };
67
- }
68
- if (rule.minValue !== undefined && value < rule.minValue) {
69
- return { valid: false, error: `${path} must be at least ${rule.minValue}` };
70
- }
71
- if (rule.maxValue !== undefined && value > rule.maxValue) {
72
- return { valid: false, error: `${path} must be at most ${rule.maxValue}` };
73
- }
74
- if (rule.enumValues && !rule.enumValues.includes(value)) {
75
- return { valid: false, error: `${path} must be one of: ${rule.enumValues.join(', ')}` };
76
- }
77
- break;
78
-
79
- case 'boolean':
80
- if (typeof value !== 'boolean') {
81
- return { valid: false, error: `${path} must be a boolean` };
82
- }
83
- break;
84
-
85
- case 'date':
86
- if (typeof value !== 'string') {
87
- return { valid: false, error: `${path} must be an ISO date string` };
88
- }
89
- if (isNaN(Date.parse(value))) {
90
- return { valid: false, error: `${path} must be a valid ISO date string` };
91
- }
92
- break;
93
-
94
- case 'array':
95
- if (!Array.isArray(value)) {
96
- return { valid: false, error: `${path} must be an array` };
97
- }
98
- if (rule.minLength && value.length < rule.minLength) {
99
- return { valid: false, error: `${path} must have at least ${rule.minLength} items` };
100
- }
101
- if (rule.maxLength && value.length > rule.maxLength) {
102
- return { valid: false, error: `${path} must have at most ${rule.maxLength} items` };
103
- }
104
- if (rule.items) {
105
- for (let i = 0; i < value.length; i++) {
106
- const itemResult = validateValue(value[i], rule.items, `${path}[${i}]`);
107
- if (!itemResult.valid) return itemResult;
108
- }
109
- }
110
- break;
111
-
112
- case 'object':
113
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
114
- return { valid: false, error: `${path} must be an object` };
115
- }
116
- if (rule.properties) {
117
- const nestedResult = validate(value, rule.properties);
118
- if (!nestedResult.valid) {
119
- return { valid: false, error: `${path}: ${nestedResult.error}` };
120
- }
121
- }
122
- break;
123
-
124
- case 'enum':
125
- if (!rule.enumValues?.includes(value as string | number)) {
126
- return { valid: false, error: `${path} must be one of: ${rule.enumValues?.join(', ')}` };
127
- }
128
- break;
129
- }
130
-
131
- return { valid: true };
132
- }
133
-
134
- // Pre-built schemas for common tool patterns
135
- export const ValidationSchemas = {
136
- stringArray: (minLength = 0): ValidationRule => ({
137
- type: 'array',
138
- required: true,
139
- minLength,
140
- items: { type: 'string' },
141
- }),
142
-
143
- entityArray: (): ValidationRule => ({
144
- type: 'array',
145
- required: true,
146
- items: {
147
- type: 'object',
148
- properties: {
149
- name: { type: 'string', required: true },
150
- entityType: { type: 'string', required: true },
151
- observations: { type: 'array', required: true, items: { type: 'string' } },
152
- },
153
- },
154
- }),
155
-
156
- relationArray: (): ValidationRule => ({
157
- type: 'array',
158
- required: true,
159
- items: {
160
- type: 'object',
161
- properties: {
162
- from: { type: 'string', required: true },
163
- to: { type: 'string', required: true },
164
- relationType: { type: 'string', required: true },
165
- },
166
- },
167
- }),
168
-
169
- isoDate: (): ValidationRule => ({
170
- type: 'date',
171
- required: true,
172
- }),
173
-
174
- nonEmptyString: (): ValidationRule => ({
175
- type: 'string',
176
- required: true,
177
- minLength: 1,
178
- }),
179
- };
package/src/pde/index.ts DELETED
@@ -1,8 +0,0 @@
1
- /**
2
- * PDE module — Prompt Decomposition Engine → Structural Tension Chart transformation
3
- */
4
-
5
- export { StcMapper, stcMapper } from './stc-mapper.js';
6
- export { SessionManager, sessionManager } from './session-manager.js';
7
- export { PDE_MCP_TOOLS } from './mcp-tools.js';
8
- export { handlePdeTool } from './mcp-handlers.js';
@@ -1,359 +0,0 @@
1
- /**
2
- * PDE MCP tool dispatch — handles each tool by calling stcMapper + sessionManager
3
- * Ported from coaia-pde/src/mcp-server.ts handler logic
4
- */
5
-
6
- import type { DecompositionResult, McpToolResult } from '../types.js';
7
- import { stcMapper } from './stc-mapper.js';
8
- import { sessionManager } from './session-manager.js';
9
-
10
- export async function handlePdeTool(
11
- name: string,
12
- args: Record<string, unknown>
13
- ): Promise<McpToolResult> {
14
- try {
15
- switch (name) {
16
- case 'import_pde_decomposition': {
17
- const pdeId = args.pde_id as string;
18
- const workdir = args.workdir as string | undefined;
19
-
20
- const stored = await sessionManager.loadPdeDecomposition(pdeId, workdir);
21
- if (!stored) {
22
- throw new Error(`PDE decomposition ${pdeId} not found in .pde/ directory`);
23
- }
24
-
25
- const { entities, relations, chartId } = stcMapper.mapDecompositionToChart(
26
- stored.result,
27
- stored.prompt,
28
- { pdeId: stored.id }
29
- );
30
-
31
- const session = await sessionManager.initSession(stored.prompt, chartId, stored.id);
32
- for (const entity of entities) {
33
- await sessionManager.appendEntity(session.sessionId, entity);
34
- }
35
- for (const relation of relations) {
36
- await sessionManager.appendRelation(session.sessionId, relation);
37
- }
38
-
39
- const desiredOutcome = entities.find(e => e.entityType === 'desired_outcome')?.observations[0];
40
- const currentReality = entities.find(e => e.entityType === 'current_reality')?.observations;
41
- const actionSteps = entities
42
- .filter(e => e.entityType === 'action_step')
43
- .map(e => ({ name: e.name, description: e.observations[0] }));
44
-
45
- return {
46
- content: [{
47
- type: 'text',
48
- text: JSON.stringify({
49
- success: true,
50
- sessionId: session.sessionId,
51
- chartId,
52
- pdeDecompositionId: stored.id,
53
- filePath: await sessionManager.getSessionFilePath(session.sessionId),
54
- chart: { desiredOutcome, currentReality, actionSteps },
55
- }, null, 2)
56
- }]
57
- };
58
- }
59
-
60
- case 'create_stc_from_pde': {
61
- const resultJson = args.decomposition_result as DecompositionResult;
62
- const originalPrompt = args.original_prompt as string;
63
-
64
- const { entities, relations, chartId } = stcMapper.mapDecompositionToChart(
65
- resultJson,
66
- originalPrompt
67
- );
68
-
69
- const session = await sessionManager.initSession(originalPrompt, chartId);
70
- for (const entity of entities) {
71
- await sessionManager.appendEntity(session.sessionId, entity);
72
- }
73
- for (const relation of relations) {
74
- await sessionManager.appendRelation(session.sessionId, relation);
75
- }
76
-
77
- const desiredOutcome = entities.find(e => e.entityType === 'desired_outcome')?.observations[0];
78
- const currentReality = entities.find(e => e.entityType === 'current_reality')?.observations;
79
- const actionSteps = entities
80
- .filter(e => e.entityType === 'action_step')
81
- .map(e => ({ name: e.name, description: e.observations[0] }));
82
-
83
- return {
84
- content: [{
85
- type: 'text',
86
- text: JSON.stringify({
87
- success: true,
88
- sessionId: session.sessionId,
89
- chartId,
90
- filePath: await sessionManager.getSessionFilePath(session.sessionId),
91
- chart: { desiredOutcome, currentReality, actionSteps },
92
- }, null, 2)
93
- }]
94
- };
95
- }
96
-
97
- case 'list_pde_decompositions': {
98
- const workdir = args.workdir as string | undefined;
99
- const decompositions = await sessionManager.listPdeDecompositions(workdir);
100
-
101
- return {
102
- content: [{
103
- type: 'text',
104
- text: JSON.stringify({
105
- count: decompositions.length,
106
- decompositions: decompositions.map(d => ({
107
- id: d.id,
108
- timestamp: d.timestamp,
109
- prompt: d.prompt.substring(0, 100) + (d.prompt.length > 100 ? '...' : '')
110
- }))
111
- }, null, 2)
112
- }]
113
- };
114
- }
115
-
116
- case 'get_session': {
117
- const sessionId = args.session_id as string;
118
- const { session, entities } = await sessionManager.loadSession(sessionId);
119
-
120
- const chart = entities.find(e => e.entityType === 'structural_tension_chart');
121
- const desiredOutcome = entities.find(e => e.entityType === 'desired_outcome');
122
- const currentReality = entities.find(e => e.entityType === 'current_reality');
123
- const actionSteps = entities.filter(e => e.entityType === 'action_step');
124
-
125
- const completedCount = actionSteps.filter(a => a.metadata?.completionStatus).length;
126
- const progress = actionSteps.length > 0 ? completedCount / actionSteps.length : 0;
127
-
128
- return {
129
- content: [{
130
- type: 'text',
131
- text: JSON.stringify({
132
- session,
133
- chart: {
134
- chartId: chart?.metadata?.chartId,
135
- desiredOutcome: desiredOutcome?.observations[0],
136
- currentReality: currentReality?.observations,
137
- dueDate: chart?.metadata?.dueDate,
138
- progress: Math.round(progress * 100) + '%',
139
- completedActions: completedCount,
140
- totalActions: actionSteps.length
141
- },
142
- actionSteps: actionSteps.map(a => ({
143
- name: a.name,
144
- description: a.observations[0],
145
- completed: a.metadata?.completionStatus || false,
146
- dueDate: a.metadata?.dueDate,
147
- progress: a.observations.slice(1)
148
- }))
149
- }, null, 2)
150
- }]
151
- };
152
- }
153
-
154
- case 'list_sessions': {
155
- const status = args.status as string | undefined;
156
- let sessions = await sessionManager.listSessions();
157
-
158
- if (status && status !== 'all') {
159
- sessions = sessions.filter(s => s.status === status);
160
- }
161
-
162
- return {
163
- content: [{
164
- type: 'text',
165
- text: JSON.stringify({
166
- count: sessions.length,
167
- sessions: sessions.map(s => ({
168
- sessionId: s.sessionId,
169
- status: s.status,
170
- createdAt: s.createdAt,
171
- pdeDecompositionId: s.pdeDecompositionId,
172
- prompt: s.originalPrompt.substring(0, 100) + (s.originalPrompt.length > 100 ? '...' : '')
173
- }))
174
- }, null, 2)
175
- }]
176
- };
177
- }
178
-
179
- case 'update_action_progress': {
180
- const sessionId = args.session_id as string;
181
- const actionName = args.action_name as string;
182
- const observation = args.observation as string;
183
- const updateCR = args.update_current_reality as boolean | undefined;
184
-
185
- const { entities } = await sessionManager.loadSession(sessionId);
186
- const action = entities.find(e => e.name === actionName);
187
-
188
- if (!action) {
189
- throw new Error(`Action step ${actionName} not found`);
190
- }
191
-
192
- action.observations.push(observation);
193
- await sessionManager.updateEntity(sessionId, actionName, { observations: action.observations });
194
-
195
- if (updateCR) {
196
- const chartId = action.metadata?.chartId;
197
- const realityName = `${chartId}_current_reality`;
198
- const reality = entities.find(e => e.name === realityName);
199
- if (reality) {
200
- reality.observations.push(`Progress: ${observation}`);
201
- await sessionManager.updateEntity(sessionId, realityName, { observations: reality.observations });
202
- }
203
- }
204
-
205
- return {
206
- content: [{
207
- type: 'text',
208
- text: JSON.stringify({ success: true, actionName, observation })
209
- }]
210
- };
211
- }
212
-
213
- case 'mark_action_complete': {
214
- const sessionId = args.session_id as string;
215
- const actionName = args.action_name as string;
216
- const completionNote = args.completion_note as string | undefined;
217
-
218
- const { entities } = await sessionManager.loadSession(sessionId);
219
- const action = entities.find(e => e.name === actionName);
220
-
221
- if (!action) {
222
- throw new Error(`Action step ${actionName} not found`);
223
- }
224
-
225
- if (!action.metadata) action.metadata = {};
226
- action.metadata.completionStatus = true;
227
- action.metadata.updatedAt = new Date().toISOString();
228
-
229
- if (completionNote) {
230
- action.observations.push(`Completed: ${completionNote}`);
231
- }
232
-
233
- await sessionManager.updateEntity(sessionId, actionName, {
234
- observations: action.observations,
235
- metadata: action.metadata
236
- });
237
-
238
- const chartId = action.metadata?.chartId;
239
- const realityName = `${chartId}_current_reality`;
240
- const reality = entities.find(e => e.name === realityName);
241
- if (reality) {
242
- reality.observations.push(`Completed: ${action.observations[0]}`);
243
- await sessionManager.updateEntity(sessionId, realityName, { observations: reality.observations });
244
- }
245
-
246
- return {
247
- content: [{
248
- type: 'text',
249
- text: JSON.stringify({ success: true, actionName, completed: true })
250
- }]
251
- };
252
- }
253
-
254
- case 'add_action_step': {
255
- const sessionId = args.session_id as string;
256
- const description = args.action_description as string;
257
- const currentReality = args.current_reality as string | undefined;
258
-
259
- const { session, entities } = await sessionManager.loadSession(sessionId);
260
- const chart = entities.find(e => e.entityType === 'structural_tension_chart');
261
- const chartId = (chart?.metadata?.chartId as string) || session.masterChartId;
262
-
263
- const existingActions = entities.filter(e => e.entityType === 'action_step');
264
- const actionNum = existingActions.length + 1;
265
- const actionName = `${chartId}_action_${actionNum}`;
266
- const now = new Date().toISOString();
267
-
268
- const newAction = {
269
- name: actionName,
270
- entityType: 'action_step',
271
- observations: currentReality ? [description, `Current: ${currentReality}`] : [description],
272
- metadata: {
273
- chartId,
274
- completionStatus: false,
275
- level: 1,
276
- parentChart: chartId,
277
- createdAt: now,
278
- updatedAt: now,
279
- }
280
- };
281
-
282
- await sessionManager.appendEntity(sessionId, newAction);
283
- await sessionManager.appendRelation(sessionId, {
284
- from: `${chartId}_chart`,
285
- to: actionName,
286
- relationType: 'has_action_step',
287
- metadata: { createdAt: now }
288
- });
289
-
290
- return {
291
- content: [{
292
- type: 'text',
293
- text: JSON.stringify({ success: true, actionName, description })
294
- }]
295
- };
296
- }
297
-
298
- case 'update_current_reality': {
299
- const sessionId = args.session_id as string;
300
- const observations = args.observations as string[];
301
-
302
- const { session, entities } = await sessionManager.loadSession(sessionId);
303
- const chartId = session.masterChartId;
304
- const realityName = `${chartId}_current_reality`;
305
- const reality = entities.find(e => e.name === realityName);
306
-
307
- if (!reality) {
308
- throw new Error(`Current reality not found for chart ${chartId}`);
309
- }
310
-
311
- reality.observations.push(...observations);
312
- await sessionManager.updateEntity(sessionId, realityName, { observations: reality.observations });
313
-
314
- return {
315
- content: [{
316
- type: 'text',
317
- text: JSON.stringify({ success: true, added: observations.length, totalObservations: reality.observations.length })
318
- }]
319
- };
320
- }
321
-
322
- case 'complete_session': {
323
- const sessionId = args.session_id as string;
324
- const finalNote = args.final_note as string | undefined;
325
-
326
- await sessionManager.updateSession(sessionId, { status: 'completed' });
327
-
328
- if (finalNote) {
329
- const { session, entities } = await sessionManager.loadSession(sessionId);
330
- const realityName = `${session.masterChartId}_current_reality`;
331
- const reality = entities.find(e => e.name === realityName);
332
- if (reality) {
333
- reality.observations.push(`Final: ${finalNote}`);
334
- await sessionManager.updateEntity(sessionId, realityName, { observations: reality.observations });
335
- }
336
- }
337
-
338
- return {
339
- content: [{
340
- type: 'text',
341
- text: JSON.stringify({ success: true, sessionId, status: 'completed' })
342
- }]
343
- };
344
- }
345
-
346
- default:
347
- throw new Error(`Unknown PDE tool: ${name}`);
348
- }
349
- } catch (error: unknown) {
350
- const message = error instanceof Error ? error.message : String(error);
351
- return {
352
- content: [{
353
- type: 'text',
354
- text: `Error: ${message}`,
355
- }],
356
- isError: true
357
- };
358
- }
359
- }