@pikku/inspector 0.12.56 → 0.12.59
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 +185 -0
- package/dist/add/add-ai-agent.js +25 -0
- package/dist/add/add-ai-scorer.d.ts +2 -0
- package/dist/add/add-ai-scorer.js +61 -0
- package/dist/add/add-wire-addon.js +26 -0
- package/dist/add/scenario-instrumentation.d.ts +6 -1
- package/dist/add/scenario-instrumentation.js +6 -0
- package/dist/error-codes.d.ts +2 -0
- package/dist/error-codes.js +3 -0
- package/dist/inspector.js +7 -3
- package/dist/types.d.ts +24 -0
- package/dist/utils/filter-inspector-state.js +8 -0
- package/dist/utils/post-process.d.ts +13 -3
- package/dist/utils/post-process.js +51 -21
- package/dist/utils/serialize-inspector-state.d.ts +11 -0
- package/dist/utils/serialize-inspector-state.js +8 -0
- package/dist/utils/workflow/dsl/extract-dsl-workflow.js +13 -4
- package/dist/utils/workflow/dsl/patterns.d.ts +2 -1
- package/dist/utils/workflow/dsl/patterns.js +8 -5
- package/dist/utils/workflow/graph/workflow-graph.types.d.ts +2 -1
- package/dist/visit.js +2 -0
- package/package.json +3 -3
- package/src/add/add-ai-agent.ts +35 -0
- package/src/add/add-ai-scorer.test.ts +197 -0
- package/src/add/add-ai-scorer.ts +83 -0
- package/src/add/add-functions.ts +1 -1
- package/src/add/add-scenario-step.test.ts +21 -1
- package/src/add/add-wire-addon.test.ts +74 -0
- package/src/add/add-wire-addon.ts +22 -0
- package/src/add/scenario-instrumentation.ts +6 -0
- package/src/error-codes.ts +4 -0
- package/src/inspector.ts +7 -3
- package/src/types.ts +21 -0
- package/src/utils/filter-inspector-state.ts +8 -0
- package/src/utils/post-process.test.ts +138 -0
- package/src/utils/post-process.ts +69 -22
- package/src/utils/serialize-inspector-state.ts +16 -0
- package/src/utils/workflow/dsl/extract-approval-policy.test.ts +68 -0
- package/src/utils/workflow/dsl/extract-dsl-workflow.ts +13 -5
- package/src/utils/workflow/dsl/patterns.ts +8 -5
- package/src/utils/workflow/graph/workflow-graph.types.ts +1 -1
- package/src/visit.ts +2 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/src/utils/secret-brokers.test.ts +0 -53
- package/src/utils/secret-brokers.ts +0 -11
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { describe, test } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import * as ts from 'typescript'
|
|
4
|
+
import { extractDSLWorkflow } from './extract-dsl-workflow.js'
|
|
5
|
+
import type { ApprovalStepMeta } from '@pikku/core/workflow'
|
|
6
|
+
|
|
7
|
+
const checker = {
|
|
8
|
+
getSymbolAtLocation: () => undefined,
|
|
9
|
+
getAliasedSymbol: () => undefined,
|
|
10
|
+
getShorthandAssignmentValueSymbol: () => undefined,
|
|
11
|
+
getTypeAtLocation: () => undefined,
|
|
12
|
+
} as unknown as ts.TypeChecker
|
|
13
|
+
|
|
14
|
+
/** Extracts the single approval step from a workflow body. */
|
|
15
|
+
const approvalStepFor = (options: string): ApprovalStepMeta => {
|
|
16
|
+
const file = ts.createSourceFile(
|
|
17
|
+
'wf.ts',
|
|
18
|
+
`const wf = pikkuWorkflowFunc({
|
|
19
|
+
func: async (services, data, { workflow }) => {
|
|
20
|
+
await workflow.approval('Release funds', ${options})
|
|
21
|
+
},
|
|
22
|
+
})`,
|
|
23
|
+
ts.ScriptTarget.Latest,
|
|
24
|
+
true
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
let node: ts.Node | undefined
|
|
28
|
+
const visit = (n: ts.Node) => {
|
|
29
|
+
if (ts.isCallExpression(n) && n.expression.getText() === 'pikkuWorkflowFunc') {
|
|
30
|
+
node = n
|
|
31
|
+
}
|
|
32
|
+
ts.forEachChild(n, visit)
|
|
33
|
+
}
|
|
34
|
+
visit(file)
|
|
35
|
+
assert.ok(node, 'failed to find the workflow definition')
|
|
36
|
+
|
|
37
|
+
const result = extractDSLWorkflow(node, checker)
|
|
38
|
+
assert.equal(result.status, 'ok', JSON.stringify(result))
|
|
39
|
+
const step = result.steps?.find(
|
|
40
|
+
(s): s is ApprovalStepMeta => s.type === 'approval'
|
|
41
|
+
)
|
|
42
|
+
assert.ok(step, 'no approval step was extracted')
|
|
43
|
+
return step
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
describe('an approval gate carries its policy into the graph', () => {
|
|
47
|
+
test('approvers and approverScope survive extraction', () => {
|
|
48
|
+
const step = approvalStepFor(
|
|
49
|
+
`{ schema: DecisionSchema, approvers: 'not-initiator', approverScope: 'payments:approve' }`
|
|
50
|
+
)
|
|
51
|
+
assert.equal(step.approvers, 'not-initiator')
|
|
52
|
+
assert.equal(step.approverScope, 'payments:approve')
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
test('expiry still survives alongside them', () => {
|
|
56
|
+
const step = approvalStepFor(
|
|
57
|
+
`{ schema: DecisionSchema, expiry: '3d', approvers: 'owner' }`
|
|
58
|
+
)
|
|
59
|
+
assert.equal(step.expiry, '3d')
|
|
60
|
+
assert.equal(step.approvers, 'owner')
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
test('a gate declaring no policy records none', () => {
|
|
64
|
+
const step = approvalStepFor(`{ schema: DecisionSchema }`)
|
|
65
|
+
assert.equal(step.approvers, undefined)
|
|
66
|
+
assert.equal(step.approverScope, undefined)
|
|
67
|
+
})
|
|
68
|
+
})
|
|
@@ -15,13 +15,13 @@ import type {
|
|
|
15
15
|
SwitchCaseMeta,
|
|
16
16
|
FilterStepMeta,
|
|
17
17
|
ArrayPredicateStepMeta,
|
|
18
|
-
ScenarioStepMeta,
|
|
19
18
|
InputSource,
|
|
20
19
|
OutputBinding,
|
|
21
20
|
Condition,
|
|
22
21
|
WorkflowContext,
|
|
23
22
|
ContextVariable,
|
|
24
23
|
} from '@pikku/core/workflow'
|
|
24
|
+
import type { ScenarioStepMeta } from '@pikku/core/scenario'
|
|
25
25
|
import {
|
|
26
26
|
isWorkflowDoCall,
|
|
27
27
|
isWorkflowExpectEventuallyCall,
|
|
@@ -1051,14 +1051,15 @@ function extractApprovalStep(
|
|
|
1051
1051
|
step.outputVar = outputVar
|
|
1052
1052
|
}
|
|
1053
1053
|
// The `schema` option is a runtime value validated inside the workflow body,
|
|
1054
|
-
// so it is deliberately not serialized here — only
|
|
1055
|
-
// and planned-step ladder need in order to describe the gate.
|
|
1054
|
+
// so it is deliberately not serialized here — only the literal options the
|
|
1055
|
+
// graph and planned-step ladder need in order to describe the gate.
|
|
1056
1056
|
const options = args[1]
|
|
1057
1057
|
if (options && ts.isObjectLiteralExpression(options)) {
|
|
1058
1058
|
for (const prop of options.properties) {
|
|
1059
|
+
if (!ts.isPropertyAssignment(prop)) continue
|
|
1060
|
+
const name = prop.name.getText()
|
|
1059
1061
|
if (
|
|
1060
|
-
|
|
1061
|
-
prop.name.getText() === 'expiry' &&
|
|
1062
|
+
name === 'expiry' &&
|
|
1062
1063
|
(ts.isStringLiteral(prop.initializer) ||
|
|
1063
1064
|
ts.isNumericLiteral(prop.initializer))
|
|
1064
1065
|
) {
|
|
@@ -1066,6 +1067,13 @@ function extractApprovalStep(
|
|
|
1066
1067
|
? Number(prop.initializer.text)
|
|
1067
1068
|
: prop.initializer.text
|
|
1068
1069
|
}
|
|
1070
|
+
if (name === 'approvers' && ts.isStringLiteral(prop.initializer)) {
|
|
1071
|
+
step.approvers = prop.initializer
|
|
1072
|
+
.text as ApprovalStepMeta['approvers']
|
|
1073
|
+
}
|
|
1074
|
+
if (name === 'approverScope' && ts.isStringLiteral(prop.initializer)) {
|
|
1075
|
+
step.approverScope = prop.initializer.text
|
|
1076
|
+
}
|
|
1069
1077
|
}
|
|
1070
1078
|
}
|
|
1071
1079
|
return step
|
|
@@ -77,20 +77,23 @@ export function getScenarioStepPhase(
|
|
|
77
77
|
/**
|
|
78
78
|
* The expectation helpers that assert without being a `then`.
|
|
79
79
|
*
|
|
80
|
-
* `expectService` and `
|
|
81
|
-
* steps, so they carry no phase and never reach the step meta — but
|
|
82
|
-
* a witness: a recorded service call,
|
|
83
|
-
* a scenario whose only assertion is one of these
|
|
80
|
+
* `expectService`, `expectError` and `expectScore` are inline steps rather than
|
|
81
|
+
* scenario steps, so they carry no phase and never reach the step meta — but
|
|
82
|
+
* each one is a witness: a recorded service call, a refusal, or a graded run.
|
|
83
|
+
* PKU680 has to see them, or a scenario whose only assertion is one of these
|
|
84
|
+
* reads as asserting nothing.
|
|
84
85
|
*/
|
|
85
86
|
const SCENARIO_EXPECTATION_CALLS = [
|
|
86
87
|
'expectService',
|
|
87
88
|
'expectError',
|
|
88
89
|
'expectEventually',
|
|
90
|
+
'expectScore',
|
|
89
91
|
] as const
|
|
90
92
|
|
|
91
93
|
/**
|
|
92
94
|
* Check if a call expression is one of the scenario expectation helpers —
|
|
93
|
-
* `scenario.expectService()`, `.expectError()
|
|
95
|
+
* `scenario.expectService()`, `.expectError()`, `.expectEventually()` or
|
|
96
|
+
* `.expectScore()`.
|
|
94
97
|
*/
|
|
95
98
|
export function isScenarioExpectationCall(node: ts.CallExpression): boolean {
|
|
96
99
|
return (
|
|
@@ -113,10 +113,10 @@ export type FlowType =
|
|
|
113
113
|
// Import and re-export context types from core
|
|
114
114
|
import type {
|
|
115
115
|
ContextVariable,
|
|
116
|
-
ScenarioStepPhase,
|
|
117
116
|
WorkflowContext,
|
|
118
117
|
WorkflowPlannedStep,
|
|
119
118
|
} from '@pikku/core/workflow'
|
|
119
|
+
import type { ScenarioStepPhase } from '@pikku/core/scenario'
|
|
120
120
|
|
|
121
121
|
export type { ContextVariable, WorkflowContext }
|
|
122
122
|
|
package/src/visit.ts
CHANGED
|
@@ -34,6 +34,7 @@ import { addVariable } from './add/add-variable.js'
|
|
|
34
34
|
import { addWorkflowGraph } from './add/add-workflow-graph.js'
|
|
35
35
|
import { addFeature } from './add/add-feature.js'
|
|
36
36
|
import { addAIAgent } from './add/add-ai-agent.js'
|
|
37
|
+
import { addAIScorer } from './add/add-ai-scorer.js'
|
|
37
38
|
import { addApprovalDescription } from './add/add-approval-description.js'
|
|
38
39
|
|
|
39
40
|
export const visitSetup = (
|
|
@@ -172,6 +173,7 @@ export const visitRoutes = (
|
|
|
172
173
|
addWorkflowGraph(logger, node, checker, state, nextOptions)
|
|
173
174
|
addFeature(logger, node, checker, state, nextOptions)
|
|
174
175
|
addAIAgent(logger, node, checker, state, nextOptions)
|
|
176
|
+
addAIScorer(logger, node, checker, state, nextOptions)
|
|
175
177
|
|
|
176
178
|
ts.forEachChild(node, (child) =>
|
|
177
179
|
visitRoutes(logger, checker, child, state, nextOptions)
|