@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.
- package/CHANGELOG.md +143 -0
- package/LICENSE +21 -0
- package/dist/function/function-runner.js +7 -2
- package/dist/handle-error.d.ts +2 -0
- package/dist/handle-error.js +8 -2
- package/dist/schema.d.ts +24 -0
- package/dist/schema.js +46 -0
- package/dist/services/in-memory-queue-service.d.ts +6 -0
- package/dist/services/in-memory-queue-service.js +8 -1
- package/dist/services/in-memory-workflow-service.d.ts +3 -5
- package/dist/services/in-memory-workflow-service.js +10 -19
- package/dist/services/workflow-service.d.ts +7 -5
- package/dist/types/core.types.d.ts +7 -0
- package/dist/wirings/ai-agent/ai-agent-agui.js +0 -8
- package/dist/wirings/ai-agent/ai-agent-prepare.js +1 -2
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +0 -6
- package/dist/wirings/http/http-runner.d.ts +1 -1
- package/dist/wirings/http/http-runner.js +4 -2
- package/dist/wirings/http/http.types.d.ts +2 -0
- package/dist/wirings/http/index.d.ts +2 -1
- package/dist/wirings/http/index.js +1 -1
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +11 -1
- package/dist/wirings/http/pikku-fetch-http-request.js +67 -3
- package/dist/wirings/mcp/mcp-runner.d.ts +5 -0
- package/dist/wirings/mcp/mcp-runner.js +5 -2
- package/dist/wirings/workflow/graph/graph-runner.js +3 -2
- package/dist/wirings/workflow/graph/graph-validation.d.ts +0 -2
- package/dist/wirings/workflow/graph/graph-validation.js +0 -142
- package/dist/wirings/workflow/graph/index.d.ts +1 -1
- package/dist/wirings/workflow/graph/index.js +1 -1
- package/dist/wirings/workflow/index.d.ts +0 -1
- package/dist/wirings/workflow/index.js +0 -2
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +69 -15
- package/dist/wirings/workflow/pikku-workflow-service.js +260 -164
- package/dist/wirings/workflow/workflow.types.d.ts +1 -6
- package/package.json +1 -2
- package/src/function/function-runner.test.ts +75 -0
- package/src/function/function-runner.ts +15 -2
- package/src/gopass-secrets-removed.test.ts +51 -0
- package/src/handle-error.test.ts +108 -1
- package/src/handle-error.ts +10 -2
- package/src/schema.test.ts +103 -0
- package/src/schema.ts +51 -0
- package/src/services/in-memory-queue-service.test.ts +66 -1
- package/src/services/in-memory-queue-service.ts +13 -2
- package/src/services/in-memory-workflow-service.ts +12 -25
- package/src/services/workflow-service.ts +7 -4
- package/src/types/core.types.ts +7 -0
- package/src/wirings/ai-agent/ai-agent-agui.test.ts +0 -16
- package/src/wirings/ai-agent/ai-agent-agui.ts +0 -9
- package/src/wirings/ai-agent/ai-agent-prepare.ts +1 -2
- package/src/wirings/ai-agent/ai-agent.types.ts +0 -7
- package/src/wirings/http/http-runner.ts +4 -1
- package/src/wirings/http/http.types.ts +2 -0
- package/src/wirings/http/index.ts +5 -1
- package/src/wirings/http/pikku-fetch-http-request.test.ts +89 -0
- package/src/wirings/http/pikku-fetch-http-request.ts +85 -3
- package/src/wirings/mcp/mcp-runner.test.ts +40 -0
- package/src/wirings/mcp/mcp-runner.ts +11 -2
- package/src/wirings/workflow/graph/graph-runner.ts +3 -2
- package/src/wirings/workflow/graph/graph-validation.test.ts +1 -144
- package/src/wirings/workflow/graph/graph-validation.ts +0 -196
- package/src/wirings/workflow/graph/index.ts +1 -5
- package/src/wirings/workflow/index.ts +0 -6
- package/src/wirings/workflow/pikku-workflow-service.ts +377 -212
- package/src/wirings/workflow/scenario-expectations.test.ts +153 -0
- package/src/wirings/workflow/scenario-step.test.ts +1 -1
- package/src/wirings/workflow/workflow-dispatch-durability.test.ts +1 -1
- package/src/wirings/workflow/workflow-dispatch-payload.test.ts +59 -0
- package/src/wirings/workflow/workflow-mirror.test.ts +178 -0
- package/src/wirings/workflow/workflow-replay-snapshot.test.ts +139 -0
- package/src/wirings/workflow/workflow-run-context.test.ts +177 -0
- package/src/wirings/workflow/workflow-run-polling.test.ts +132 -0
- package/src/wirings/workflow/workflow-step-ordinal.test.ts +4 -4
- package/src/wirings/workflow/workflow.types.ts +1 -4
- package/tsconfig.tsbuildinfo +1 -1
- 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,
|