jev-devtools 0.1.3 → 0.3.0
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/README.md +50 -4
- package/THIRD_PARTY_NOTICES.txt +27 -0
- package/lib/flow/index.d.ts +82 -0
- package/lib/flow/index.js +588 -0
- package/lib/server/flows.d.ts +25 -0
- package/lib/server/flows.js +115 -0
- package/lib/server/index.d.ts +8 -0
- package/lib/server/index.js +163 -9
- package/lib/server/recorder.d.ts +12 -2
- package/lib/server/recorder.js +47 -9
- package/lib/src/ChoiceProbabilities.d.ts +4 -0
- package/lib/src/ChoiceProbabilities.js +19 -0
- package/lib/src/ConnectedInspector.js +46 -29
- package/lib/src/DiagramContent.d.ts +6 -0
- package/lib/src/DiagramContent.js +32 -0
- package/lib/src/FlowOverview.d.ts +7 -0
- package/lib/src/FlowOverview.js +228 -0
- package/lib/src/JevDevtools.d.ts +6 -1
- package/lib/src/JevDevtools.js +52 -48
- package/lib/src/JevDrawer.d.ts +3 -2
- package/lib/src/JevDrawer.js +12 -3
- package/lib/src/Questions.d.ts +5 -0
- package/lib/src/Questions.js +174 -0
- package/lib/src/TraceContent.d.ts +11 -0
- package/lib/src/TraceContent.js +32 -0
- package/lib/src/TraceDiagram.d.ts +4 -1
- package/lib/src/TraceDiagram.js +111 -25
- package/lib/src/condition-inputs.d.ts +9 -0
- package/lib/src/condition-inputs.js +100 -0
- package/lib/src/flow-condition.d.ts +4 -0
- package/lib/src/flow-condition.js +47 -0
- package/lib/src/flow-model.d.ts +7 -2
- package/lib/src/flow-model.js +3 -12
- package/lib/src/flow-protocol.d.ts +68 -0
- package/lib/src/flow-protocol.js +1 -0
- package/lib/src/flow-stream.d.ts +8 -0
- package/lib/src/flow-stream.js +80 -0
- package/lib/src/index.d.ts +1 -1
- package/lib/src/inspector-styles.js +1 -1
- package/lib/src/inspector.css +725 -8
- package/lib/src/protocol.d.ts +18 -0
- package/lib/src/trace-store.d.ts +6 -0
- package/lib/src/trace-store.js +66 -0
- package/lib/src/trace-stream.d.ts +2 -0
- package/lib/src/trace-stream.js +65 -0
- package/lib/src/useDiagramViewport.d.ts +5 -0
- package/lib/src/useDiagramViewport.js +34 -6
- package/package.json +7 -2
- package/skills/setup-jev-devtools/SKILL.md +6 -2
- package/skills/setup-jev-devtools/references/flows.md +150 -0
- package/skills/setup-jev-devtools/references/nextjs.md +1 -1
- package/skills/setup-jev-devtools/references/verify.md +3 -1
package/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# Jev DevTools
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/jev-devtools/v/0.3.0)
|
|
4
4
|
|
|
5
5
|
A React drawer and Node adapter for inspecting TypeSafe Jev requests with animated diagrams. Includes request history, context, questions, typed answers, transport attempts, and raw snapshots.
|
|
6
6
|
|
|
7
|
-
**Experimental
|
|
7
|
+
**Experimental (pre-1.0).** React 18/19 and Node 22.12+ are supported. APIs may change before 1.0. Verification uses sample responses through the real TypeSafe SDK, not live inference.
|
|
8
|
+
|
|
9
|
+
[Changelog and release history](https://github.com/diegoag64/jev-devtools/blob/main/CHANGELOG.md) — published versions and unreleased work.
|
|
8
10
|
|
|
9
11
|
## Demo
|
|
10
12
|
|
|
@@ -42,7 +44,7 @@ To try unpublished local changes instead:
|
|
|
42
44
|
npm ci
|
|
43
45
|
npm run pack:devtools
|
|
44
46
|
# From the consuming app:
|
|
45
|
-
npm install /absolute/path/to/jev-devtools-0.
|
|
47
|
+
npm install /absolute/path/to/jev-devtools-0.3.0.tgz
|
|
46
48
|
```
|
|
47
49
|
|
|
48
50
|
Mount once:
|
|
@@ -69,7 +71,7 @@ app.use(inspector.middleware); // Mount at root, before fallback handlers.
|
|
|
69
71
|
// Call inspector.dispose() on shutdown.
|
|
70
72
|
```
|
|
71
73
|
|
|
72
|
-
Only calls through that client are captured. The React component subscribes via same-origin SSE. Both sides default to disabled. API keys remain server-side. Browser code is SSR-safe. The drawer uses a Shadow DOM boundary and its own stylesheet so host page selectors cannot alter its internal layout. Existing stylesheet imports remain supported; no Tailwind or shadcn installation is required. Drag the Flow canvas to pan, scroll/pinch to zoom, or use Fit.
|
|
74
|
+
Only calls through that client are captured. The React component subscribes via same-origin SSE, receiving an initial snapshot followed by changed traces. Older client/server combinations remain compatible through full snapshots. Both sides default to disabled. API keys remain server-side. Browser code is SSR-safe. The drawer uses a Shadow DOM boundary and its own stylesheet so host page selectors cannot alter its internal layout. Existing stylesheet imports remain supported; no Tailwind or shadcn installation is required. Drag the Flow canvas to pan, scroll/pinch to zoom, or use Fit.
|
|
73
75
|
|
|
74
76
|
History is bounded to 50 calls in memory by default. API routes and inspector endpoints must share an adapter instance; distributed processes and edge runtimes are not supported. Non-loopback use requires explicit authorization. Captures include bounded/redacted context and answers, not hidden model reasoning.
|
|
75
77
|
|
|
@@ -78,3 +80,47 @@ For Next.js App Router, use `getJevDevtools(appKey, optionsFactory)` from `/serv
|
|
|
78
80
|
[Full integration guide](https://github.com/diegoag64/jev-devtools/blob/main/docs/integration.md) · [Repository and playground](https://github.com/diegoag64/jev-devtools)
|
|
79
81
|
|
|
80
82
|
MIT for project code. See bundled LICENSE and THIRD_PARTY_NOTICES.txt for original design attribution and TypeSafe branding.
|
|
83
|
+
|
|
84
|
+
## Connected Jev flows
|
|
85
|
+
|
|
86
|
+
New in **0.3.0**: define calls, conditions, parallel checks, and named outcomes with `jev-devtools/flow`. The drawer connects each request's complete diagram on one canvas. Condition cards show the incoming value and its requirement; optional titles and descriptions explain each step. Existing single-request integrations need no changes.
|
|
87
|
+
|
|
88
|
+
On the server, reuse the instrumented `jev` client and `inspector` from the setup above:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { defineJevFlow } from 'jev-devtools/flow';
|
|
92
|
+
|
|
93
|
+
const review = defineJevFlow<{ message: string }>('review', (flow) => {
|
|
94
|
+
const decision = flow.jev('readiness', {
|
|
95
|
+
state: flow.input,
|
|
96
|
+
questions: { ready: { type: 'noul', instructions: 'Is this ready for review?' } },
|
|
97
|
+
}, { title: 'Assess readiness' });
|
|
98
|
+
|
|
99
|
+
return flow.branch('route', {
|
|
100
|
+
when: decision.answer('ready').noul.gte(0.9), // Your application's policy.
|
|
101
|
+
then: (path) => path.output('ready', { probability: decision.answer('ready').noul }, {
|
|
102
|
+
title: 'Ready for review', description: 'Return readiness to the application.',
|
|
103
|
+
}),
|
|
104
|
+
else: (path) => path.output('manual-review', undefined, { title: 'Needs manual review' }),
|
|
105
|
+
}, { title: 'Require at least 90% readiness' });
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const result = await review.run({ message: 'Please review my ticket.' }, {
|
|
109
|
+
client: jev,
|
|
110
|
+
devtools: inspector,
|
|
111
|
+
});
|
|
112
|
+
// Handle result.outcome in your app. The flow does not execute business actions.
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Define once in a Node module and run per request. Use `flow.parallel` for concurrent named lanes; downstream calls wait for every lane to succeed. Branches are terminal in their block. Runs are in-process, with bounded inspector history, SDK retries, and cancellation support; they are not durable workflows.
|
|
116
|
+
|
|
117
|
+
[Full flow guide](https://github.com/diegoag64/jev-devtools/blob/main/docs/flows.md) · [AI flow recipe](https://github.com/diegoag64/jev-devtools/blob/main/packages/jev-devtools/skills/setup-jev-devtools/references/flows.md)
|
|
118
|
+
|
|
119
|
+
To have your coding agent add a flow after installation:
|
|
120
|
+
|
|
121
|
+
```text
|
|
122
|
+
Read node_modules/jev-devtools/skills/setup-jev-devtools/SKILL.md and references/flows.md.
|
|
123
|
+
Build a flow for the scenario I describe using the shared server client/inspector.
|
|
124
|
+
Preserve my routing policies, add clear step titles/descriptions, and verify with
|
|
125
|
+
labeled samples before using live inference. Ask for any missing decision rules.
|
|
126
|
+
```
|
package/THIRD_PARTY_NOTICES.txt
CHANGED
|
@@ -48,3 +48,30 @@ trademark rights or imply endorsement.
|
|
|
48
48
|
The playground uses shadcn/ui components. Its MIT notice is preserved in
|
|
49
49
|
apps/playground/SHADCN_LICENSE.md. Those components are not bundled in the
|
|
50
50
|
DevTools package. No TanStack DevTools shell is included.
|
|
51
|
+
|
|
52
|
+
TanStack Virtual
|
|
53
|
+
|
|
54
|
+
Questions virtualization uses @tanstack/react-virtual and @tanstack/virtual-core.
|
|
55
|
+
https://github.com/TanStack/virtual
|
|
56
|
+
|
|
57
|
+
MIT License
|
|
58
|
+
|
|
59
|
+
Copyright (c) 2021-present Tanner Linsley
|
|
60
|
+
|
|
61
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
62
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
63
|
+
in the Software without restriction, including without limitation the rights
|
|
64
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
65
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
66
|
+
furnished to do so, subject to the following conditions:
|
|
67
|
+
|
|
68
|
+
The above copyright notice and this permission notice shall be included in all
|
|
69
|
+
copies or substantial portions of the Software.
|
|
70
|
+
|
|
71
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
72
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
73
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
74
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
75
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
76
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
77
|
+
SOFTWARE.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { Questions, ResultFor, SystemOneRequest, TypeSafeClient } from "@typesafe-ai/sdk";
|
|
2
|
+
import type { FlowDefinition, FlowDisplay, FlowRun } from "../src/flow-protocol.js";
|
|
3
|
+
export type { FlowDisplay, FlowDefinition, FlowRun, FlowStep, } from "../src/flow-protocol.js";
|
|
4
|
+
type Ast = {
|
|
5
|
+
op: "input";
|
|
6
|
+
} | {
|
|
7
|
+
op: "ref";
|
|
8
|
+
id: string;
|
|
9
|
+
} | {
|
|
10
|
+
op: "get";
|
|
11
|
+
from: Ast;
|
|
12
|
+
key: string;
|
|
13
|
+
} | {
|
|
14
|
+
op: "literal";
|
|
15
|
+
value: unknown;
|
|
16
|
+
} | {
|
|
17
|
+
op: "eq" | "lt" | "gte" | "all" | "any" | "not";
|
|
18
|
+
args: Ast[];
|
|
19
|
+
};
|
|
20
|
+
/** Inspectable expression, not an application callback. Use get() for input fields. */
|
|
21
|
+
export declare class FlowExpression<T> {
|
|
22
|
+
readonly ast: Ast;
|
|
23
|
+
private readonly valueType;
|
|
24
|
+
constructor(ast: Ast, owner?: object);
|
|
25
|
+
get<K extends keyof T & (string | number)>(key: K): FlowExpression<T[K]>;
|
|
26
|
+
eq(value: T | FlowExpression<T>): FlowExpression<boolean>;
|
|
27
|
+
lt(this: FlowExpression<number>, value: number | FlowExpression<number>): FlowExpression<boolean>;
|
|
28
|
+
gte(this: FlowExpression<number>, value: number | FlowExpression<number>): FlowExpression<boolean>;
|
|
29
|
+
}
|
|
30
|
+
export declare const all: (...conditions: FlowExpression<boolean>[]) => FlowExpression<boolean>;
|
|
31
|
+
export declare const any: (...conditions: FlowExpression<boolean>[]) => FlowExpression<boolean>;
|
|
32
|
+
export declare const not: (condition: FlowExpression<boolean>) => FlowExpression<boolean>;
|
|
33
|
+
export type FlowOutcome = {
|
|
34
|
+
outcome: string;
|
|
35
|
+
value?: unknown;
|
|
36
|
+
};
|
|
37
|
+
type AnswerRefs<Q extends Questions> = {
|
|
38
|
+
answer<K extends keyof Q & string>(name: K): {
|
|
39
|
+
[F in keyof ResultFor<Q[K]>]: FlowExpression<ResultFor<Q[K]>[F]>;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
type Request<Q extends Questions> = Omit<SystemOneRequest<Q>, "state"> & {
|
|
43
|
+
state: unknown;
|
|
44
|
+
};
|
|
45
|
+
/** Observer contract used by createJevDevtools; execution never depends on successful recording. */
|
|
46
|
+
export type FlowObserver = {
|
|
47
|
+
startFlow(definition: FlowDefinition, run: FlowRun): {
|
|
48
|
+
update(run: FlowRun): void;
|
|
49
|
+
request<T>(link: {
|
|
50
|
+
runId: string;
|
|
51
|
+
stepId: string;
|
|
52
|
+
executionId: string;
|
|
53
|
+
}, onTrace: (id: string) => void, callback: () => T): T;
|
|
54
|
+
} | undefined;
|
|
55
|
+
};
|
|
56
|
+
export type FlowRunOptions = {
|
|
57
|
+
client: Pick<TypeSafeClient, "systemOne">;
|
|
58
|
+
devtools?: FlowObserver;
|
|
59
|
+
signal?: AbortSignal;
|
|
60
|
+
};
|
|
61
|
+
export interface FlowBuilder<T> {
|
|
62
|
+
readonly input: FlowExpression<T>;
|
|
63
|
+
jev<const Q extends Questions>(id: string, request: Request<Q>, display?: FlowDisplay): AnswerRefs<Q>;
|
|
64
|
+
/** Terminal decision: each callback must return output() or another branch(). */
|
|
65
|
+
branch(id: string, paths: {
|
|
66
|
+
when: FlowExpression<boolean>;
|
|
67
|
+
then: (path: FlowBuilder<T>) => FlowExpression<FlowOutcome>;
|
|
68
|
+
else: (path: FlowBuilder<T>) => FlowExpression<FlowOutcome>;
|
|
69
|
+
}, display?: FlowDisplay): FlowExpression<FlowOutcome>;
|
|
70
|
+
parallel<const B extends Record<string, (lane: FlowBuilder<T>) => FlowExpression<unknown>>>(id: string, lanes: B, display?: FlowDisplay): {
|
|
71
|
+
[K in keyof B]: ReturnType<B[K]>;
|
|
72
|
+
};
|
|
73
|
+
output(name: string, value?: unknown, display?: FlowDisplay): FlowExpression<FlowOutcome>;
|
|
74
|
+
}
|
|
75
|
+
export declare function defineJevFlow<T>(name: string, build: (flow: FlowBuilder<T>) => FlowExpression<FlowOutcome>): {
|
|
76
|
+
definition: FlowDefinition;
|
|
77
|
+
run(data: T, options: FlowRunOptions): Promise<{
|
|
78
|
+
runId: string;
|
|
79
|
+
outcome: string;
|
|
80
|
+
value?: unknown;
|
|
81
|
+
}>;
|
|
82
|
+
};
|