@nmzpy/pi-ember-stack 0.1.6 → 0.2.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.
- package/README.md +83 -83
- package/package.json +62 -48
- package/plugins/devin-auth/extensions/index.ts +68 -7
- package/plugins/devin-auth/src/cloud-direct/auth.ts +246 -246
- package/plugins/devin-auth/src/cloud-direct/catalog.ts +246 -246
- package/plugins/devin-auth/src/cloud-direct/chat.ts +1096 -1091
- package/plugins/devin-auth/src/cloud-direct/index.ts +41 -41
- package/plugins/devin-auth/src/cloud-direct/metadata.ts +78 -78
- package/plugins/devin-auth/src/cloud-direct/wire.ts +202 -202
- package/plugins/devin-auth/src/models.ts +42 -196
- package/plugins/devin-auth/src/oauth/register-user.ts +174 -174
- package/plugins/devin-auth/src/oauth/types.ts +71 -71
- package/plugins/devin-auth/src/stream.ts +1 -1
- package/plugins/index.ts +29 -6
- package/plugins/pi-compact-tools/index.ts +35 -192
- package/plugins/pi-compact-tools/renderer.ts +589 -0
- package/plugins/pi-custom-agents/index.ts +727 -373
- package/plugins/pi-custom-agents/questionnaire-tool.ts +14 -5
- package/plugins/pi-custom-agents/subagent/agents/coder.md +1 -0
- package/plugins/pi-custom-agents/subagent/agents/scout.md +16 -37
- package/plugins/pi-custom-agents/subagent/extensions/agents.ts +18 -1
- package/plugins/pi-custom-agents/subagent/extensions/index.ts +118 -226
- package/plugins/pi-custom-agents/subagent/extensions/model.ts +96 -96
- package/plugins/pi-custom-agents/subagent/extensions/render.ts +205 -1
- package/plugins/pi-custom-agents/subagent/extensions/runner.ts +260 -170
- package/plugins/pi-custom-agents/subagent/extensions/test/render.test.ts +145 -0
- package/plugins/pi-ember-fff/index.ts +975 -0
- package/plugins/pi-ember-fff/query.ts +247 -0
- package/plugins/pi-ember-fff/test/query.test.ts +222 -0
- package/plugins/pi-ember-fff/test/renderer.test.ts +727 -0
- package/plugins/pi-ember-tps/index.ts +144 -0
- package/plugins/pi-ember-ui/ember.json +99 -0
- package/plugins/pi-ember-ui/index.ts +805 -0
- package/plugins/pi-ember-ui/mode-colors.ts +196 -0
- package/tsconfig.json +2 -1
- package/plugins/pi-custom-agents/subagent/agents/architect.md +0 -56
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ember TPS Meter — minimal tokens-per-second tracker
|
|
3
|
+
*
|
|
4
|
+
* Tracks output plus thinking token rate during streaming and exposes the live
|
|
5
|
+
* value via getLiveTps() for the custom footer to render.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
9
|
+
|
|
10
|
+
const STREAM_INTERVAL_MS = 500;
|
|
11
|
+
|
|
12
|
+
let streamStartMs = 0;
|
|
13
|
+
let firstTokenMs = 0;
|
|
14
|
+
let streamChars = 0;
|
|
15
|
+
let streamThinkingChars = 0;
|
|
16
|
+
let streamTokens = 0;
|
|
17
|
+
let tickTimer: ReturnType<typeof setInterval> | null = null;
|
|
18
|
+
let streaming = false;
|
|
19
|
+
let liveTps = 0;
|
|
20
|
+
let renderTrigger: (() => void) | undefined;
|
|
21
|
+
|
|
22
|
+
function now(): number {
|
|
23
|
+
return performance.now();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function tokEst(ch: number): number {
|
|
27
|
+
return (ch >>> 2) + ((ch & 3) > 0 ? 1 : 0);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function computeTps(): number {
|
|
31
|
+
const ref = firstTokenMs > 0 ? firstTokenMs : streamStartMs;
|
|
32
|
+
const elapsed = (now() - ref) / 1000;
|
|
33
|
+
return elapsed > 0.3 ? streamTokens / elapsed : 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function startTick(): void {
|
|
37
|
+
if (tickTimer) return;
|
|
38
|
+
tickTimer = setInterval(() => {
|
|
39
|
+
if (!streaming) {
|
|
40
|
+
stopTick();
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
liveTps = computeTps();
|
|
44
|
+
renderTrigger?.();
|
|
45
|
+
}, STREAM_INTERVAL_MS);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function stopTick(): void {
|
|
49
|
+
if (tickTimer) {
|
|
50
|
+
clearInterval(tickTimer);
|
|
51
|
+
tickTimer = null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function getLiveTps(): number {
|
|
56
|
+
return liveTps;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default function piEmberTps(pi: ExtensionAPI): void {
|
|
60
|
+
pi.on("message_start", async (event, ctx) => {
|
|
61
|
+
if (event.message.role !== "assistant") return;
|
|
62
|
+
streamStartMs = now();
|
|
63
|
+
firstTokenMs = 0;
|
|
64
|
+
streamChars = 0;
|
|
65
|
+
streamThinkingChars = 0;
|
|
66
|
+
streamTokens = 0;
|
|
67
|
+
liveTps = 0;
|
|
68
|
+
streaming = true;
|
|
69
|
+
if (ctx.mode === "tui") {
|
|
70
|
+
renderTrigger = () => ctx.ui.setStatus("tps", undefined);
|
|
71
|
+
}
|
|
72
|
+
startTick();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
pi.on("message_update", async (event) => {
|
|
76
|
+
if (event.message.role !== "assistant") return;
|
|
77
|
+
if (!event.assistantMessageEvent) return;
|
|
78
|
+
const evt = event.assistantMessageEvent;
|
|
79
|
+
if (evt.type === "text_delta" || evt.type === "thinking_delta") {
|
|
80
|
+
const d = evt.delta as string;
|
|
81
|
+
if (!d) return;
|
|
82
|
+
if (firstTokenMs === 0) firstTokenMs = now();
|
|
83
|
+
streamChars += d.length;
|
|
84
|
+
if (evt.type === "thinking_delta") streamThinkingChars += d.length;
|
|
85
|
+
streamTokens = tokEst(streamChars);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
pi.on("message_end", async (event) => {
|
|
90
|
+
if (event.message.role !== "assistant") return;
|
|
91
|
+
streaming = false;
|
|
92
|
+
stopTick();
|
|
93
|
+
|
|
94
|
+
const usage = event.message?.usage;
|
|
95
|
+
const realOut = usage?.output;
|
|
96
|
+
// Some providers report output tokens without their thinking tokens.
|
|
97
|
+
// Keep the streamed combined estimate in that case; providers that
|
|
98
|
+
// expose `reasoning` already include it in `usage.output`.
|
|
99
|
+
const tokens = typeof realOut === "number" && realOut > 0
|
|
100
|
+
? streamThinkingChars > 0 && usage?.reasoning === undefined
|
|
101
|
+
? Math.max(realOut, streamTokens)
|
|
102
|
+
: realOut
|
|
103
|
+
: streamTokens;
|
|
104
|
+
|
|
105
|
+
const ref = firstTokenMs > 0 ? firstTokenMs : streamStartMs;
|
|
106
|
+
const elapsed = (now() - ref) / 1000;
|
|
107
|
+
if (elapsed < 0.1 || tokens === 0) {
|
|
108
|
+
liveTps = 0;
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
liveTps = tokens / elapsed;
|
|
113
|
+
renderTrigger?.();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
pi.on("agent_end", async () => {
|
|
117
|
+
streaming = false;
|
|
118
|
+
stopTick();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
122
|
+
streaming = false;
|
|
123
|
+
stopTick();
|
|
124
|
+
streamStartMs = 0;
|
|
125
|
+
firstTokenMs = 0;
|
|
126
|
+
streamChars = 0;
|
|
127
|
+
streamThinkingChars = 0;
|
|
128
|
+
streamTokens = 0;
|
|
129
|
+
liveTps = 0;
|
|
130
|
+
renderTrigger = undefined;
|
|
131
|
+
ctx.ui.setStatus("tps", undefined);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Clear the tick interval and stale render trigger on shutdown so a
|
|
135
|
+
// subsequent /resume does not keep a setInterval alive against the dead
|
|
136
|
+
// session's ctx.ui. Without this, the 500ms tick keeps firing and
|
|
137
|
+
// calls the old renderTrigger long after the session is gone.
|
|
138
|
+
pi.on("session_shutdown", async () => {
|
|
139
|
+
streaming = false;
|
|
140
|
+
stopTick();
|
|
141
|
+
renderTrigger = undefined;
|
|
142
|
+
liveTps = 0;
|
|
143
|
+
});
|
|
144
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
3
|
+
"name": "ember",
|
|
4
|
+
"vars": {
|
|
5
|
+
"emberAccent": "#EB6E00",
|
|
6
|
+
"emberAccent90": "#EB6E00",
|
|
7
|
+
"emberAccent75": "#D9640F",
|
|
8
|
+
"emberAccent60": "#C25A17",
|
|
9
|
+
"emberAccent45": "#A8501F",
|
|
10
|
+
"emberAccent30": "#8F4627",
|
|
11
|
+
"emberAccent15": "#783C2F",
|
|
12
|
+
"emberAccent25": "#4D2E17",
|
|
13
|
+
"emberGray": "#808080",
|
|
14
|
+
"emberDarkGray": "#505050",
|
|
15
|
+
"cyan": "#00d7ff",
|
|
16
|
+
"blue": "#5f87ff",
|
|
17
|
+
"green": "#b5bd68",
|
|
18
|
+
"red": "#cc6666",
|
|
19
|
+
"yellow": "#ffff00",
|
|
20
|
+
"text": "#d4d4d4",
|
|
21
|
+
"gray": "#808080",
|
|
22
|
+
"dimGray": "#666666",
|
|
23
|
+
"darkGray": "#505050",
|
|
24
|
+
"accent": "#EB6E00",
|
|
25
|
+
"selectedBg": "#3a3a4a",
|
|
26
|
+
"userMsgBg": "#343541",
|
|
27
|
+
"subagentBg": "#32333f",
|
|
28
|
+
"toolPendingBg": "#282832",
|
|
29
|
+
"toolSuccessBg": "#283228",
|
|
30
|
+
"toolErrorBg": "#3c2828",
|
|
31
|
+
"customMsgBg": "#2d2838"
|
|
32
|
+
},
|
|
33
|
+
"colors": {
|
|
34
|
+
"accent": "emberAccent",
|
|
35
|
+
"border": "emberAccent",
|
|
36
|
+
"borderAccent": "emberAccent",
|
|
37
|
+
"borderMuted": "emberDarkGray",
|
|
38
|
+
"success": "green",
|
|
39
|
+
"error": "red",
|
|
40
|
+
"warning": "yellow",
|
|
41
|
+
"muted": "gray",
|
|
42
|
+
"dim": "dimGray",
|
|
43
|
+
"text": "text",
|
|
44
|
+
"thinkingText": "gray",
|
|
45
|
+
|
|
46
|
+
"selectedBg": "selectedBg",
|
|
47
|
+
"userMessageBg": "userMsgBg",
|
|
48
|
+
"subagentBg": "subagentBg",
|
|
49
|
+
"userMessageText": "text",
|
|
50
|
+
"customMessageBg": "customMsgBg",
|
|
51
|
+
"customMessageText": "text",
|
|
52
|
+
"customMessageLabel": "#9575cd",
|
|
53
|
+
"toolPendingBg": "toolPendingBg",
|
|
54
|
+
"toolSuccessBg": "toolSuccessBg",
|
|
55
|
+
"toolErrorBg": "toolErrorBg",
|
|
56
|
+
"toolTitle": "text",
|
|
57
|
+
"toolOutput": "gray",
|
|
58
|
+
|
|
59
|
+
"mdHeading": "#f0c674",
|
|
60
|
+
"mdLink": "#81a2be",
|
|
61
|
+
"mdLinkUrl": "dimGray",
|
|
62
|
+
"mdCode": "text",
|
|
63
|
+
"mdCodeBlock": "green",
|
|
64
|
+
"mdCodeBlockBorder": "gray",
|
|
65
|
+
"mdQuote": "gray",
|
|
66
|
+
"mdQuoteBorder": "gray",
|
|
67
|
+
"mdHr": "gray",
|
|
68
|
+
"mdListBullet": "emberAccent",
|
|
69
|
+
|
|
70
|
+
"toolDiffAdded": "green",
|
|
71
|
+
"toolDiffRemoved": "red",
|
|
72
|
+
"toolDiffContext": "gray",
|
|
73
|
+
|
|
74
|
+
"syntaxComment": "#6A9955",
|
|
75
|
+
"syntaxKeyword": "#569CD6",
|
|
76
|
+
"syntaxFunction": "#DCDCAA",
|
|
77
|
+
"syntaxVariable": "#9CDCFE",
|
|
78
|
+
"syntaxString": "#CE9178",
|
|
79
|
+
"syntaxNumber": "#B5CEA8",
|
|
80
|
+
"syntaxType": "#4EC9B0",
|
|
81
|
+
"syntaxOperator": "#D4D4D4",
|
|
82
|
+
"syntaxPunctuation": "#D4D4D4",
|
|
83
|
+
|
|
84
|
+
"thinkingOff": "emberDarkGray",
|
|
85
|
+
"thinkingMinimal": "emberAccent15",
|
|
86
|
+
"thinkingLow": "emberAccent30",
|
|
87
|
+
"thinkingMedium": "emberAccent45",
|
|
88
|
+
"thinkingHigh": "emberAccent60",
|
|
89
|
+
"thinkingXhigh": "emberAccent75",
|
|
90
|
+
"thinkingMax": "emberAccent90",
|
|
91
|
+
|
|
92
|
+
"bashMode": "green"
|
|
93
|
+
},
|
|
94
|
+
"export": {
|
|
95
|
+
"pageBg": "#18181e",
|
|
96
|
+
"cardBg": "#1e1e24",
|
|
97
|
+
"infoBg": "#3c3728"
|
|
98
|
+
}
|
|
99
|
+
}
|