ai-whisper 0.12.0 → 0.12.1
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.
|
@@ -856,7 +856,7 @@ function listSessionAttachmentsByCollab(db, collabId2) {
|
|
|
856
856
|
|
|
857
857
|
// ../broker/dist/storage/repositories/duo-assignment-repository.js
|
|
858
858
|
import { z as z18 } from "zod";
|
|
859
|
-
var duoRoleSchema = z18.enum(["reviewer", "implementer"]);
|
|
859
|
+
var duoRoleSchema = z18.enum(["body", "brain", "reviewer", "implementer"]).transform((value) => value === "reviewer" ? "brain" : value === "implementer" ? "body" : value);
|
|
860
860
|
var duoRollSlotSchema = z18.object({
|
|
861
861
|
characterId: z18.string().min(1),
|
|
862
862
|
characterName: z18.string().min(1),
|
|
@@ -889,7 +889,7 @@ function listSessionAttachmentsByCollab(db, collabId) {
|
|
|
889
889
|
|
|
890
890
|
// ../broker/dist/storage/repositories/duo-assignment-repository.js
|
|
891
891
|
import { z as z18 } from "zod";
|
|
892
|
-
var duoRoleSchema = z18.enum(["reviewer", "implementer"]);
|
|
892
|
+
var duoRoleSchema = z18.enum(["body", "brain", "reviewer", "implementer"]).transform((value) => value === "reviewer" ? "brain" : value === "implementer" ? "body" : value);
|
|
893
893
|
var duoRollSlotSchema = z18.object({
|
|
894
894
|
characterId: z18.string().min(1),
|
|
895
895
|
characterName: z18.string().min(1),
|
|
@@ -859,7 +859,7 @@ function listSessionAttachmentsByCollab(db, collabId2) {
|
|
|
859
859
|
|
|
860
860
|
// ../broker/dist/storage/repositories/duo-assignment-repository.js
|
|
861
861
|
import { z as z18 } from "zod";
|
|
862
|
-
var duoRoleSchema = z18.enum(["reviewer", "implementer"]);
|
|
862
|
+
var duoRoleSchema = z18.enum(["body", "brain", "reviewer", "implementer"]).transform((value) => value === "reviewer" ? "brain" : value === "implementer" ? "body" : value);
|
|
863
863
|
var duoRollSlotSchema = z18.object({
|
|
864
864
|
characterId: z18.string().min(1),
|
|
865
865
|
characterName: z18.string().min(1),
|
package/dist/bin/whisper.js
CHANGED
|
@@ -1309,7 +1309,7 @@ var duoRoleSchema, duoRollSlotSchema, proposedDuoRollSchema;
|
|
|
1309
1309
|
var init_duo_assignment_repository = __esm({
|
|
1310
1310
|
"../broker/dist/storage/repositories/duo-assignment-repository.js"() {
|
|
1311
1311
|
"use strict";
|
|
1312
|
-
duoRoleSchema = z18.enum(["reviewer", "implementer"]);
|
|
1312
|
+
duoRoleSchema = z18.enum(["body", "brain", "reviewer", "implementer"]).transform((value) => value === "reviewer" ? "brain" : value === "implementer" ? "body" : value);
|
|
1313
1313
|
duoRollSlotSchema = z18.object({
|
|
1314
1314
|
characterId: z18.string().min(1),
|
|
1315
1315
|
characterName: z18.string().min(1),
|
|
@@ -8883,6 +8883,7 @@ var DUOS = [
|
|
|
8883
8883
|
characters: [
|
|
8884
8884
|
{
|
|
8885
8885
|
id: "sherlock",
|
|
8886
|
+
role: "brain",
|
|
8886
8887
|
displayName: "Sherlock",
|
|
8887
8888
|
summonName: "SHERLOCK",
|
|
8888
8889
|
punchline: "Elementary, my dear Watson.",
|
|
@@ -8890,6 +8891,7 @@ var DUOS = [
|
|
|
8890
8891
|
},
|
|
8891
8892
|
{
|
|
8892
8893
|
id: "watson",
|
|
8894
|
+
role: "body",
|
|
8893
8895
|
displayName: "Watson",
|
|
8894
8896
|
summonName: "WATSON",
|
|
8895
8897
|
punchline: "By Jove, Holmes \u2014 it works!",
|
|
@@ -8902,6 +8904,7 @@ var DUOS = [
|
|
|
8902
8904
|
characters: [
|
|
8903
8905
|
{
|
|
8904
8906
|
id: "frankenstein",
|
|
8907
|
+
role: "brain",
|
|
8905
8908
|
displayName: "Frankenstein",
|
|
8906
8909
|
summonName: "FRANKENSTEIN",
|
|
8907
8910
|
punchline: "It's alive! IT'S ALIVE!",
|
|
@@ -8909,6 +8912,7 @@ var DUOS = [
|
|
|
8909
8912
|
},
|
|
8910
8913
|
{
|
|
8911
8914
|
id: "igor",
|
|
8915
|
+
role: "body",
|
|
8912
8916
|
displayName: "Igor",
|
|
8913
8917
|
summonName: "IGOR",
|
|
8914
8918
|
punchline: "It's pronounced 'eye-gor'.",
|
|
@@ -8921,6 +8925,7 @@ var DUOS = [
|
|
|
8921
8925
|
characters: [
|
|
8922
8926
|
{
|
|
8923
8927
|
id: "quixote",
|
|
8928
|
+
role: "brain",
|
|
8924
8929
|
displayName: "Don Quixote",
|
|
8925
8930
|
summonName: "DON QUIXOTE",
|
|
8926
8931
|
punchline: "Those are not windmills \u2014 they are giants!",
|
|
@@ -8928,6 +8933,7 @@ var DUOS = [
|
|
|
8928
8933
|
},
|
|
8929
8934
|
{
|
|
8930
8935
|
id: "sancho",
|
|
8936
|
+
role: "body",
|
|
8931
8937
|
displayName: "Sancho Panza",
|
|
8932
8938
|
summonName: "SANCHO PANZA",
|
|
8933
8939
|
punchline: "Se\xF1or... those are windmills.",
|
|
@@ -8940,6 +8946,7 @@ var DUOS = [
|
|
|
8940
8946
|
characters: [
|
|
8941
8947
|
{
|
|
8942
8948
|
id: "c3po",
|
|
8949
|
+
role: "body",
|
|
8943
8950
|
displayName: "C-3PO",
|
|
8944
8951
|
summonName: "C-3PO",
|
|
8945
8952
|
punchline: "We're doomed!",
|
|
@@ -8947,6 +8954,7 @@ var DUOS = [
|
|
|
8947
8954
|
},
|
|
8948
8955
|
{
|
|
8949
8956
|
id: "r2d2",
|
|
8957
|
+
role: "brain",
|
|
8950
8958
|
displayName: "R2-D2",
|
|
8951
8959
|
summonName: "R2-D2",
|
|
8952
8960
|
punchline: "Beep boop bee-boop.",
|
|
@@ -8959,6 +8967,7 @@ var DUOS = [
|
|
|
8959
8967
|
characters: [
|
|
8960
8968
|
{
|
|
8961
8969
|
id: "batman",
|
|
8970
|
+
role: "brain",
|
|
8962
8971
|
displayName: "Batman",
|
|
8963
8972
|
summonName: "BATMAN",
|
|
8964
8973
|
punchline: "I'm Batman.",
|
|
@@ -8966,6 +8975,7 @@ var DUOS = [
|
|
|
8966
8975
|
},
|
|
8967
8976
|
{
|
|
8968
8977
|
id: "robin",
|
|
8978
|
+
role: "body",
|
|
8969
8979
|
displayName: "Robin",
|
|
8970
8980
|
summonName: "ROBIN",
|
|
8971
8981
|
punchline: "Holy merge conflict, Batman!",
|
|
@@ -8978,6 +8988,7 @@ var DUOS = [
|
|
|
8978
8988
|
characters: [
|
|
8979
8989
|
{
|
|
8980
8990
|
id: "rocket",
|
|
8991
|
+
role: "brain",
|
|
8981
8992
|
displayName: "Rocket",
|
|
8982
8993
|
summonName: "ROCKET",
|
|
8983
8994
|
punchline: "Ain't no thing like me, 'cept me!",
|
|
@@ -8985,6 +8996,7 @@ var DUOS = [
|
|
|
8985
8996
|
},
|
|
8986
8997
|
{
|
|
8987
8998
|
id: "groot",
|
|
8999
|
+
role: "body",
|
|
8988
9000
|
displayName: "Groot",
|
|
8989
9001
|
summonName: "GROOT",
|
|
8990
9002
|
punchline: "I am Groot.",
|
|
@@ -8997,6 +9009,7 @@ var DUOS = [
|
|
|
8997
9009
|
characters: [
|
|
8998
9010
|
{
|
|
8999
9011
|
id: "walter",
|
|
9012
|
+
role: "brain",
|
|
9000
9013
|
displayName: "Walter White",
|
|
9001
9014
|
summonName: "HEISENBERG",
|
|
9002
9015
|
punchline: "I am the one who knocks.",
|
|
@@ -9004,6 +9017,7 @@ var DUOS = [
|
|
|
9004
9017
|
},
|
|
9005
9018
|
{
|
|
9006
9019
|
id: "jesse",
|
|
9020
|
+
role: "body",
|
|
9007
9021
|
displayName: "Jesse Pinkman",
|
|
9008
9022
|
summonName: "JESSE",
|
|
9009
9023
|
punchline: "That's science, b*tch!",
|
|
@@ -9012,6 +9026,9 @@ var DUOS = [
|
|
|
9012
9026
|
]
|
|
9013
9027
|
}
|
|
9014
9028
|
];
|
|
9029
|
+
function duoRoleFlavor(role) {
|
|
9030
|
+
return role === "brain" ? "the brain of this operation" : "the body, the face, and the hair";
|
|
9031
|
+
}
|
|
9015
9032
|
function getDuo(duoId) {
|
|
9016
9033
|
return DUOS.find((duo) => duo.id === duoId);
|
|
9017
9034
|
}
|
|
@@ -14477,8 +14494,8 @@ function compareSemver(a, b) {
|
|
|
14477
14494
|
var EZIO_PROVENANCE = {
|
|
14478
14495
|
ezioCliVersion: "0.4.0",
|
|
14479
14496
|
ezioGitSha: "77a3b48",
|
|
14480
|
-
builtAt: "2026-07-
|
|
14481
|
-
whisperVersion: "0.12.
|
|
14497
|
+
builtAt: "2026-07-03T06:53:50.854Z",
|
|
14498
|
+
whisperVersion: "0.12.1"
|
|
14482
14499
|
};
|
|
14483
14500
|
|
|
14484
14501
|
// src/ezio-provenance-types.ts
|
|
@@ -16075,11 +16092,28 @@ function buildDuoHandoffFragment(input) {
|
|
|
16075
16092
|
return `[duo] You are ${input.character} (${input.role}); teammate ${input.teammateAgentType} is ${teammateDisplay}. Character flavor in prose only; never alter code, commits, or workflow verdict labels.`;
|
|
16076
16093
|
}
|
|
16077
16094
|
function buildDuoPersonaBrief(duo) {
|
|
16078
|
-
const otherRole = duo.role === "
|
|
16095
|
+
const otherRole = duo.role === "brain" ? "body" : "brain";
|
|
16079
16096
|
const teammateClause = duo.teammate === null ? " Your teammate has no character assigned yet." : duo.teammate.character === null ? ` Your teammate ${duo.teammate.agentType} has no character assigned.` : ` Your teammate ${duo.teammate.agentType} is ${duo.teammate.character}, the ${otherRole}.`;
|
|
16080
|
-
return `[ai-whisper duo] For this collab session you are ${duo.character} \u2014
|
|
16097
|
+
return `[ai-whisper duo] For this collab session you are ${duo.character} \u2014 ${duoRoleFlavor(duo.role)}.${teammateClause}
|
|
16081
16098
|
Stay in character in conversational prose only \u2014 never in code, commit messages, PR text, or file contents, and never alter workflow verdict labels.`;
|
|
16082
16099
|
}
|
|
16100
|
+
async function waitForProviderOutputSettle(input) {
|
|
16101
|
+
const now = input.now ?? Date.now;
|
|
16102
|
+
const sleep3 = input.sleep ?? ((ms) => new Promise((resolve5) => setTimeout(resolve5, ms)));
|
|
16103
|
+
const pollMs = input.pollMs ?? 50;
|
|
16104
|
+
const deadline = now() + input.maxWaitMs;
|
|
16105
|
+
for (; ; ) {
|
|
16106
|
+
const lastOutputAt = input.getLastOutputAt();
|
|
16107
|
+
const t = now();
|
|
16108
|
+
if (lastOutputAt !== null && t - lastOutputAt >= input.quietMs) {
|
|
16109
|
+
return "settled";
|
|
16110
|
+
}
|
|
16111
|
+
if (t >= deadline) {
|
|
16112
|
+
return "timeout";
|
|
16113
|
+
}
|
|
16114
|
+
await sleep3(Math.min(pollMs, deadline - t));
|
|
16115
|
+
}
|
|
16116
|
+
}
|
|
16083
16117
|
function resolveTeammateCharacterFromAssignments(assignments, teammateAgentType) {
|
|
16084
16118
|
const row = assignments.find((r) => r.agentType === teammateAgentType);
|
|
16085
16119
|
if (!row) return null;
|
|
@@ -16269,6 +16303,7 @@ function createMountSessionRuntime(input) {
|
|
|
16269
16303
|
Number(process.env.AI_WHISPER_IDLE_THRESHOLD_MS ?? "") || 3e4
|
|
16270
16304
|
);
|
|
16271
16305
|
let lastActivityAt = Date.now();
|
|
16306
|
+
let lastProviderOutputAt = null;
|
|
16272
16307
|
let agyToolInFlight = false;
|
|
16273
16308
|
try {
|
|
16274
16309
|
const turnCapture = createAssistantTurnCapture();
|
|
@@ -16303,6 +16338,7 @@ function createMountSessionRuntime(input) {
|
|
|
16303
16338
|
};
|
|
16304
16339
|
interactiveSession.onProviderOutput?.((data) => {
|
|
16305
16340
|
lastActivityAt = Date.now();
|
|
16341
|
+
lastProviderOutputAt = Date.now();
|
|
16306
16342
|
turnCapture.recordProviderOutput(data);
|
|
16307
16343
|
bracketedPaste.observe(data);
|
|
16308
16344
|
});
|
|
@@ -16431,6 +16467,19 @@ function createMountSessionRuntime(input) {
|
|
|
16431
16467
|
}
|
|
16432
16468
|
if (input.duo) {
|
|
16433
16469
|
try {
|
|
16470
|
+
if (input.target !== "ezio" && typeof interactiveSession.onProviderOutput === "function") {
|
|
16471
|
+
await waitForProviderOutputSettle({
|
|
16472
|
+
getLastOutputAt: () => lastProviderOutputAt,
|
|
16473
|
+
quietMs: Math.max(
|
|
16474
|
+
0,
|
|
16475
|
+
Number(process.env.AI_WHISPER_DUO_BRIEF_QUIET_MS ?? "") || 500
|
|
16476
|
+
),
|
|
16477
|
+
maxWaitMs: Math.max(
|
|
16478
|
+
0,
|
|
16479
|
+
Number(process.env.AI_WHISPER_DUO_BRIEF_MAX_WAIT_MS ?? "") || 1e4
|
|
16480
|
+
)
|
|
16481
|
+
});
|
|
16482
|
+
}
|
|
16434
16483
|
await submitInjectedInput2(buildDuoPersonaBrief(input.duo));
|
|
16435
16484
|
} catch (err) {
|
|
16436
16485
|
console.error(
|
|
@@ -17113,13 +17162,14 @@ function resolveDuoEnabled(duoFlag) {
|
|
|
17113
17162
|
// src/duo/roll-duo.ts
|
|
17114
17163
|
function rollDuo(rng = Math.random) {
|
|
17115
17164
|
const duo = DUOS[Math.floor(rng() * DUOS.length)];
|
|
17116
|
-
const
|
|
17117
|
-
const
|
|
17165
|
+
const body = duo.characters.find((character) => character.role === "body");
|
|
17166
|
+
const brain = duo.characters.find((character) => character.role === "brain");
|
|
17167
|
+
const toSlot = (character) => ({
|
|
17118
17168
|
characterId: character.id,
|
|
17119
17169
|
characterName: character.displayName,
|
|
17120
|
-
role:
|
|
17121
|
-
})
|
|
17122
|
-
return { duoId: duo.id, slots };
|
|
17170
|
+
role: character.role
|
|
17171
|
+
});
|
|
17172
|
+
return { duoId: duo.id, slots: [toSlot(body), toSlot(brain)] };
|
|
17123
17173
|
}
|
|
17124
17174
|
|
|
17125
17175
|
// src/duo/art-assets.ts
|
|
@@ -17158,7 +17208,7 @@ init_agent_display();
|
|
|
17158
17208
|
var RESET4 = "\x1B[0m";
|
|
17159
17209
|
var PUNCHLINE_INDENT = " ";
|
|
17160
17210
|
function renderDuoBanner(input) {
|
|
17161
|
-
const summonLine = `\u26A1 Summoning ${input.summonName}
|
|
17211
|
+
const summonLine = `\u26A1 Summoning ${input.summonName} \u2014 ${duoRoleFlavor(input.role)}...`;
|
|
17162
17212
|
const punchlineLine = `${PUNCHLINE_INDENT}"${input.punchline}"`;
|
|
17163
17213
|
const showArt = input.columns >= maxDisplayWidth(input.art);
|
|
17164
17214
|
const parts = showArt ? [summonLine, "", input.art, "", punchlineLine, RESET4] : [summonLine, punchlineLine, RESET4];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-whisper",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "Terminal-first relay for paired AI coding agents (Claude + Codex), driven by structured workflows.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
"@ai-whisper/adapter-ai-ezio": "0.0.0",
|
|
56
56
|
"@ai-whisper/adapter-antigravity": "0.0.0",
|
|
57
57
|
"@ai-whisper/adapter-codex": "0.0.0",
|
|
58
|
+
"@ai-whisper/companion-core": "0.0.0",
|
|
58
59
|
"@ai-whisper/broker": "0.0.0",
|
|
59
60
|
"@ai-whisper/adapter-claude": "0.0.0",
|
|
60
|
-
"@ai-whisper/shared": "0.0.0"
|
|
61
|
-
"@ai-whisper/companion-core": "0.0.0"
|
|
61
|
+
"@ai-whisper/shared": "0.0.0"
|
|
62
62
|
},
|
|
63
63
|
"files": [
|
|
64
64
|
"dist",
|