@pikku/core 0.12.70 → 0.12.72

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 (77) hide show
  1. package/CHANGELOG.md +143 -0
  2. package/LICENSE +21 -0
  3. package/dist/function/function-runner.js +7 -2
  4. package/dist/handle-error.d.ts +2 -0
  5. package/dist/handle-error.js +8 -2
  6. package/dist/schema.d.ts +24 -0
  7. package/dist/schema.js +46 -0
  8. package/dist/services/in-memory-queue-service.d.ts +6 -0
  9. package/dist/services/in-memory-queue-service.js +8 -1
  10. package/dist/services/in-memory-workflow-service.d.ts +3 -5
  11. package/dist/services/in-memory-workflow-service.js +10 -19
  12. package/dist/services/workflow-service.d.ts +7 -5
  13. package/dist/types/core.types.d.ts +7 -0
  14. package/dist/wirings/ai-agent/ai-agent-agui.js +0 -8
  15. package/dist/wirings/ai-agent/ai-agent-prepare.js +1 -2
  16. package/dist/wirings/ai-agent/ai-agent.types.d.ts +0 -6
  17. package/dist/wirings/http/http-runner.d.ts +1 -1
  18. package/dist/wirings/http/http-runner.js +4 -2
  19. package/dist/wirings/http/http.types.d.ts +2 -0
  20. package/dist/wirings/http/index.d.ts +2 -1
  21. package/dist/wirings/http/index.js +1 -1
  22. package/dist/wirings/http/pikku-fetch-http-request.d.ts +11 -1
  23. package/dist/wirings/http/pikku-fetch-http-request.js +67 -3
  24. package/dist/wirings/mcp/mcp-runner.d.ts +5 -0
  25. package/dist/wirings/mcp/mcp-runner.js +5 -2
  26. package/dist/wirings/workflow/graph/graph-runner.js +3 -2
  27. package/dist/wirings/workflow/graph/graph-validation.d.ts +0 -2
  28. package/dist/wirings/workflow/graph/graph-validation.js +0 -142
  29. package/dist/wirings/workflow/graph/index.d.ts +1 -1
  30. package/dist/wirings/workflow/graph/index.js +1 -1
  31. package/dist/wirings/workflow/index.d.ts +0 -1
  32. package/dist/wirings/workflow/index.js +0 -2
  33. package/dist/wirings/workflow/pikku-workflow-service.d.ts +69 -15
  34. package/dist/wirings/workflow/pikku-workflow-service.js +260 -164
  35. package/dist/wirings/workflow/workflow.types.d.ts +1 -6
  36. package/package.json +1 -2
  37. package/src/function/function-runner.test.ts +75 -0
  38. package/src/function/function-runner.ts +15 -2
  39. package/src/gopass-secrets-removed.test.ts +51 -0
  40. package/src/handle-error.test.ts +108 -1
  41. package/src/handle-error.ts +10 -2
  42. package/src/schema.test.ts +103 -0
  43. package/src/schema.ts +51 -0
  44. package/src/services/in-memory-queue-service.test.ts +66 -1
  45. package/src/services/in-memory-queue-service.ts +13 -2
  46. package/src/services/in-memory-workflow-service.ts +12 -25
  47. package/src/services/workflow-service.ts +7 -4
  48. package/src/types/core.types.ts +7 -0
  49. package/src/wirings/ai-agent/ai-agent-agui.test.ts +0 -16
  50. package/src/wirings/ai-agent/ai-agent-agui.ts +0 -9
  51. package/src/wirings/ai-agent/ai-agent-prepare.ts +1 -2
  52. package/src/wirings/ai-agent/ai-agent.types.ts +0 -7
  53. package/src/wirings/http/http-runner.ts +4 -1
  54. package/src/wirings/http/http.types.ts +2 -0
  55. package/src/wirings/http/index.ts +5 -1
  56. package/src/wirings/http/pikku-fetch-http-request.test.ts +89 -0
  57. package/src/wirings/http/pikku-fetch-http-request.ts +85 -3
  58. package/src/wirings/mcp/mcp-runner.test.ts +40 -0
  59. package/src/wirings/mcp/mcp-runner.ts +11 -2
  60. package/src/wirings/workflow/graph/graph-runner.ts +3 -2
  61. package/src/wirings/workflow/graph/graph-validation.test.ts +1 -144
  62. package/src/wirings/workflow/graph/graph-validation.ts +0 -196
  63. package/src/wirings/workflow/graph/index.ts +1 -5
  64. package/src/wirings/workflow/index.ts +0 -6
  65. package/src/wirings/workflow/pikku-workflow-service.ts +377 -212
  66. package/src/wirings/workflow/scenario-expectations.test.ts +153 -0
  67. package/src/wirings/workflow/scenario-step.test.ts +1 -1
  68. package/src/wirings/workflow/workflow-dispatch-durability.test.ts +1 -1
  69. package/src/wirings/workflow/workflow-dispatch-payload.test.ts +59 -0
  70. package/src/wirings/workflow/workflow-mirror.test.ts +178 -0
  71. package/src/wirings/workflow/workflow-replay-snapshot.test.ts +139 -0
  72. package/src/wirings/workflow/workflow-run-context.test.ts +177 -0
  73. package/src/wirings/workflow/workflow-run-polling.test.ts +132 -0
  74. package/src/wirings/workflow/workflow-step-ordinal.test.ts +4 -4
  75. package/src/wirings/workflow/workflow.types.ts +1 -4
  76. package/tsconfig.tsbuildinfo +1 -1
  77. package/src/services/gopass-secrets.ts +0 -78
@@ -1,6 +1,3 @@
1
- import { pikkuState } from '../../../pikku-state.js'
2
- import { resolveNamespace } from '../../rpc/rpc-runner.js'
3
-
4
1
  function normalizeTargets(value: unknown): string[] {
5
2
  if (!value) return []
6
3
  if (typeof value === 'string') return [value]
@@ -15,199 +12,6 @@ function normalizeTargets(value: unknown): string[] {
15
12
  return []
16
13
  }
17
14
 
18
- function collectRefs(value: unknown, refs: Set<string>): void {
19
- if (
20
- typeof value === 'object' &&
21
- value !== null &&
22
- '$ref' in value &&
23
- typeof (value as any).$ref === 'string'
24
- ) {
25
- refs.add((value as any).$ref)
26
- return
27
- }
28
- if (Array.isArray(value)) {
29
- for (const item of value) collectRefs(item, refs)
30
- return
31
- }
32
- if (typeof value === 'object' && value !== null) {
33
- for (const v of Object.values(value)) collectRefs(v, refs)
34
- }
35
- }
36
-
37
- function resolveToolMeta(toolName: string): {
38
- fnMeta: any
39
- schemas: Map<string, any>
40
- } | null {
41
- const resolved = toolName.includes(':') ? resolveNamespace(toolName) : null
42
-
43
- if (resolved) {
44
- const fnMeta = pikkuState(resolved.package, 'function', 'meta')[
45
- resolved.function
46
- ]
47
- const schemas = pikkuState(resolved.package, 'misc', 'schemas')
48
- return fnMeta ? { fnMeta, schemas } : null
49
- }
50
-
51
- const rpcMeta = pikkuState(null, 'rpc', 'meta')
52
- const pikkuFuncId = rpcMeta[toolName]
53
- if (!pikkuFuncId) return null
54
-
55
- const fnMeta = pikkuState(null, 'function', 'meta')[pikkuFuncId]
56
- const schemas = pikkuState(null, 'misc', 'schemas')
57
- return fnMeta ? { fnMeta, schemas } : null
58
- }
59
-
60
- export function computeEntryNodeIds(nodes: Record<string, any>): string[] {
61
- const referenced = new Set<string>()
62
- for (const node of Object.values(nodes)) {
63
- if (node.next) {
64
- for (const target of normalizeTargets(node.next)) {
65
- referenced.add(target)
66
- }
67
- }
68
- if (node.onError) {
69
- for (const target of normalizeTargets(node.onError)) {
70
- referenced.add(target)
71
- }
72
- }
73
- }
74
- return Object.keys(nodes).filter((id) => !referenced.has(id))
75
- }
76
-
77
- export function validateWorkflowWiring(
78
- nodes: Record<string, any>,
79
- toolNames: string[]
80
- ): string[] {
81
- const errors: string[] = []
82
- const nodeIds = new Set(Object.keys(nodes))
83
- const toolSet = new Set(toolNames)
84
-
85
- for (const [nodeId, node] of Object.entries(nodes)) {
86
- if (!node.rpcName) {
87
- errors.push(`Node '${nodeId}' is missing 'rpcName'`)
88
- continue
89
- }
90
-
91
- if (!toolSet.has(node.rpcName)) {
92
- errors.push(
93
- `Node '${nodeId}' references unknown tool '${node.rpcName}'. Available tools: ${toolNames.join(', ')}`
94
- )
95
- continue
96
- }
97
-
98
- const nextTargets = normalizeTargets(node.next)
99
- for (const target of nextTargets) {
100
- if (!nodeIds.has(target)) {
101
- errors.push(
102
- `Node '${nodeId}' routes to unknown node '${target}' in 'next'`
103
- )
104
- }
105
- }
106
-
107
- const errorTargets = normalizeTargets(node.onError)
108
- for (const target of errorTargets) {
109
- if (!nodeIds.has(target)) {
110
- errors.push(
111
- `Node '${nodeId}' routes to unknown node '${target}' in 'onError'`
112
- )
113
- }
114
- }
115
-
116
- if (!node.input) continue
117
-
118
- const refs = new Set<string>()
119
- collectRefs(node.input, refs)
120
-
121
- for (const ref of refs) {
122
- if (ref === 'trigger' || ref === '$item') {
123
- const targetMeta = resolveToolMeta(node.rpcName)
124
- if (targetMeta?.fnMeta?.inputSchemaName) {
125
- const targetSchema = targetMeta.schemas.get(
126
- targetMeta.fnMeta.inputSchemaName
127
- )
128
- if (targetSchema?.properties) {
129
- for (const [field, fieldValue] of Object.entries(
130
- node.input as Record<string, any>
131
- )) {
132
- if (
133
- typeof fieldValue === 'object' &&
134
- fieldValue !== null &&
135
- fieldValue.$ref === ref &&
136
- !fieldValue.path
137
- ) {
138
- const targetType = targetSchema.properties[field]?.type
139
- if (targetType && targetType !== 'object') {
140
- errors.push(
141
- `Node '${nodeId}' input field '${field}' expects type '${targetType}', but references the whole ${ref} object without a path. Use { $ref: "${ref}", path: "${field}" } to extract the field.`
142
- )
143
- }
144
- }
145
- }
146
- }
147
- }
148
- continue
149
- }
150
-
151
- if (!nodeIds.has(ref)) {
152
- errors.push(
153
- `Node '${nodeId}' references unknown node '${ref}' in input`
154
- )
155
- continue
156
- }
157
-
158
- const sourceNode = nodes[ref]
159
- if (!sourceNode?.rpcName) continue
160
-
161
- const sourceMeta = resolveToolMeta(sourceNode.rpcName)
162
- if (!sourceMeta?.fnMeta?.outputSchemaName) continue
163
-
164
- const sourceSchema = sourceMeta.schemas.get(
165
- sourceMeta.fnMeta.outputSchemaName
166
- )
167
- if (!sourceSchema?.properties) continue
168
-
169
- for (const [field, fieldValue] of Object.entries(
170
- node.input as Record<string, any>
171
- )) {
172
- if (
173
- typeof fieldValue === 'object' &&
174
- fieldValue !== null &&
175
- fieldValue.$ref === ref &&
176
- fieldValue.path
177
- ) {
178
- const pathRoot = fieldValue.path.split('.')[0]
179
- if (
180
- sourceSchema.properties &&
181
- !(pathRoot in sourceSchema.properties)
182
- ) {
183
- errors.push(
184
- `Node '${nodeId}' input field '${field}' references path '${fieldValue.path}' but node '${ref}' (${sourceNode.rpcName}) output has no property '${pathRoot}'`
185
- )
186
- continue
187
- }
188
-
189
- const targetMeta = resolveToolMeta(node.rpcName)
190
- if (!targetMeta?.fnMeta?.inputSchemaName) continue
191
- const targetSchema = targetMeta.schemas.get(
192
- targetMeta.fnMeta.inputSchemaName
193
- )
194
- if (!targetSchema?.properties?.[field]) continue
195
-
196
- const sourceType = sourceSchema.properties[pathRoot]?.type
197
- const targetType = targetSchema.properties[field].type
198
- if (sourceType && targetType && sourceType !== targetType) {
199
- errors.push(
200
- `Node '${nodeId}' input field '${field}' expects type '${targetType}', but node '${ref}' output field '${pathRoot}' is type '${sourceType}'`
201
- )
202
- }
203
- }
204
- }
205
- }
206
- }
207
-
208
- return errors
209
- }
210
-
211
15
  export function generateMermaidDiagram(
212
16
  workflowName: string,
213
17
  nodes: Record<string, any>,
@@ -12,8 +12,4 @@ export {
12
12
  type PikkuWorkflowGraphConfig,
13
13
  type PikkuWorkflowGraphResult,
14
14
  } from './wire-workflow-graph.js'
15
- export {
16
- validateWorkflowWiring,
17
- computeEntryNodeIds,
18
- generateMermaidDiagram,
19
- } from './graph-validation.js'
15
+ export { generateMermaidDiagram } from './graph-validation.js'
@@ -44,12 +44,6 @@ export {
44
44
  type PikkuWorkflowGraphResult,
45
45
  } from './graph/wire-workflow-graph.js'
46
46
 
47
- // Graph validation and dynamic workflow utilities
48
- export {
49
- validateWorkflowWiring,
50
- computeEntryNodeIds,
51
- } from './graph/graph-validation.js'
52
-
53
47
  // Queue worker functions (registered by codegen, executed at runtime)
54
48
  export {
55
49
  pikkuWorkflowWorkerFunc,