Compare commits
600 Commits
opus-sessi
...
opus-23avr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64832e96a4 | ||
|
|
1f4c0b5c61 | ||
|
|
e8805b9945 | ||
|
|
a9d14c7f54 | ||
|
|
70fcc001fc | ||
|
|
d4c6920bec | ||
|
|
f5824c935f | ||
|
|
171ac50d17 | ||
|
|
ce78cb3f67 | ||
|
|
dc0514bc63 | ||
|
|
5cedce019c | ||
|
|
67e0187ab6 | ||
|
|
17f92abbc6 | ||
|
|
e2bc28f242 | ||
|
|
70d4f40204 | ||
|
|
1b9b200feb | ||
|
|
808e9959eb | ||
|
|
d2c67b7dc9 | ||
|
|
efe240a0c8 | ||
|
|
f39cc6e778 | ||
|
|
7c75205269 | ||
|
|
3838c332b3 | ||
|
|
34776d5bc8 | ||
|
|
198967630c | ||
|
|
8fec004312 | ||
|
|
c9db4af34f | ||
|
|
18a20f6dda | ||
|
|
b4380d3642 | ||
|
|
1577bcf38f | ||
|
|
408ebb277a | ||
|
|
d358ad342d | ||
|
|
04bd211370 | ||
|
|
79e30e0644 | ||
|
|
4580e128fe | ||
|
|
1ba0bbd206 | ||
|
|
4eed7f8d25 | ||
|
|
eb9bb8e9cc | ||
|
|
f9b51260d5 | ||
|
|
6ad3c2a362 | ||
|
|
008cad5a5b | ||
|
|
8a7fd073d0 | ||
|
|
7c4c39dc48 | ||
|
|
5cd9e32d5c | ||
|
|
394d4bbb87 | ||
|
|
cc3276ebad | ||
|
|
a221d4be7e | ||
|
|
f0289eac98 | ||
|
|
5726e7dac3 | ||
|
|
78d1d3713d | ||
|
|
aea5a24cfd | ||
|
|
4c5f72b766 | ||
|
|
b9ffa8315c | ||
|
|
4b8905e406 | ||
|
|
4481248963 | ||
|
|
69f5719eef | ||
|
|
e0717047c3 | ||
|
|
a91b3a4092 | ||
|
|
1a6cf6dc36 | ||
|
|
501e8cd361 | ||
|
|
460d678578 | ||
|
|
1002c587a6 | ||
|
|
d36e4c73b4 | ||
|
|
a4890f8bd9 | ||
|
|
09ca85cdc8 | ||
|
|
33ec121b0e | ||
|
|
5c0881f0d9 | ||
|
|
4e12439d99 | ||
|
|
c1b6bfa470 | ||
|
|
f74bc74c3e | ||
|
|
02b8b6f550 | ||
|
|
194a52d3ce | ||
|
|
bc9be85586 | ||
|
|
8e6590195f | ||
|
|
9d0d7be098 | ||
|
|
50cfbf87b1 | ||
|
|
3a3d66b40f | ||
|
|
ffb4017240 | ||
|
|
c2feea1f20 | ||
|
|
2ffec0c6b6 | ||
|
|
ee11f88e2e | ||
|
|
a603a573b8 | ||
|
|
f36d5fb55d | ||
|
|
4e4f1d90fd | ||
|
|
424252d602 | ||
|
|
ab68896a3f | ||
|
|
136b6d7f49 | ||
|
|
d73d5e2627 | ||
|
|
d4d09e3a14 | ||
|
|
7f1166b71e | ||
|
|
fc19945678 | ||
|
|
382d14c801 | ||
|
|
7508d2ed9e | ||
|
|
5dfbbc6cc8 | ||
|
|
7880a20eeb | ||
|
|
27c4802892 | ||
|
|
97f321c25a | ||
|
|
920e599839 | ||
|
|
2ee5b084d1 | ||
|
|
38cb1e825c | ||
|
|
4fcf046347 | ||
|
|
d6359f1270 | ||
|
|
08a384d68b | ||
|
|
8bb1835ab0 | ||
|
|
c1a365cf7e | ||
|
|
51af06bd43 | ||
|
|
9dcfa100ec | ||
|
|
ab06efa13a | ||
|
|
98b5faddeb | ||
|
|
a9846d45ad | ||
|
|
7a22a8c64d | ||
|
|
ed55cac02f | ||
|
|
68cdad8a90 | ||
|
|
1279e249a5 | ||
|
|
2398ef60e0 | ||
|
|
2458acc461 | ||
|
|
6bcc227419 | ||
|
|
3836b63341 | ||
|
|
d1d0bc0da8 | ||
|
|
a64400edb5 | ||
|
|
b319c6600d | ||
|
|
58c31f04e3 | ||
|
|
8adba7e10d | ||
|
|
4d0990ce2a | ||
|
|
15935a75fb | ||
|
|
1979ff6797 | ||
|
|
91e91a1c1e | ||
|
|
54e66f92e7 | ||
|
|
ee42025a9a | ||
|
|
d9e5c6ce93 | ||
|
|
1015d3dbe5 | ||
|
|
b0fa1bd837 | ||
|
|
9bea1d902a | ||
|
|
33e2e20647 | ||
|
|
a3c9236baa | ||
|
|
7e08f4811a | ||
|
|
26e474d1ad | ||
|
|
c0f8a9a116 | ||
|
|
c2256d3f38 | ||
|
|
f96d781d06 | ||
|
|
2042d193f0 | ||
|
|
03a6bcd53a | ||
|
|
0bd9b42c34 | ||
|
|
c0ac3e9f2b | ||
|
|
570ba3a2b2 | ||
|
|
102686205b | ||
|
|
9074ac0532 | ||
|
|
15eed1516e | ||
|
|
d1674b1798 | ||
|
|
f12815efba | ||
|
|
14ac444633 | ||
|
|
de97756012 | ||
|
|
90532c6e14 | ||
|
|
d3455abcb6 | ||
|
|
4c064e3050 | ||
|
|
e674793a84 | ||
|
|
48c356cf93 | ||
|
|
fb60b32a3a | ||
|
|
6eac450a4d | ||
|
|
cbfea83283 | ||
|
|
1eaf683224 | ||
|
|
c7826b566b | ||
|
|
88ef916f71 | ||
|
|
9b58e46b2d | ||
|
|
ff7383c9fa | ||
|
|
ab5af2f9c0 | ||
|
|
c73a724e28 | ||
|
|
3f732a4f6e | ||
|
|
cc6bf77b3f | ||
|
|
2f2cfd684a | ||
|
|
f3ae5deda4 | ||
|
|
2e14c269b1 | ||
|
|
a04a0e4023 | ||
|
|
e10c32450b | ||
|
|
8b57cfd155 | ||
|
|
49bdf1c014 | ||
|
|
423d53b42c | ||
|
|
b8988c7b45 | ||
|
|
8065d93e0a | ||
|
|
a47d29a07c | ||
|
|
c38348c518 | ||
|
|
517fe3a861 | ||
|
|
110d76750a | ||
|
|
a855943b20 | ||
|
|
759b838464 | ||
|
|
6a4242416c | ||
|
|
33be450e45 | ||
|
|
02e5843a96 | ||
|
|
1cd7c4ddcb | ||
|
|
d9307131e3 | ||
|
|
83eb8780b7 | ||
|
|
d395644e1a | ||
|
|
4e2fa40c74 | ||
|
|
9cd0a23b24 | ||
|
|
12eb582411 | ||
|
|
1f811f6017 | ||
|
|
c67580ca55 | ||
|
|
ca482df1c7 | ||
|
|
d1c6df501d | ||
|
|
dc5a6a1fa7 | ||
|
|
0bb51a1816 | ||
|
|
ae0c4edbbd | ||
|
|
e18a52871a | ||
|
|
591bc1b185 | ||
|
|
83ef7d6f36 | ||
|
|
cc340623e5 | ||
|
|
e1befadf55 | ||
|
|
4f14897464 | ||
|
|
ddbd0585ab | ||
|
|
81fbf94c3b | ||
|
|
0883a741fa | ||
|
|
1d2bef4670 | ||
|
|
a19a1d8808 | ||
|
|
7507a622d4 | ||
|
|
96622a06ac | ||
|
|
423cfb7957 | ||
|
|
9e0e907011 | ||
|
|
ada60f9bb3 | ||
|
|
fed4962286 | ||
|
|
f43c1f19cd | ||
|
|
950e1def9f | ||
|
|
8ce43e9b14 | ||
|
|
bd663276da | ||
|
|
f9cce40e1a | ||
|
|
6fcf85bab9 | ||
|
|
aa293c1b18 | ||
|
|
85992385c3 | ||
|
|
dbebd38d55 | ||
|
|
854101a820 | ||
|
|
87176b1e04 | ||
|
|
92c85aae98 | ||
|
|
9764676619 | ||
|
|
5c528597d7 | ||
|
|
7123147ac8 | ||
|
|
c10da82122 | ||
|
|
c33beb3962 | ||
|
|
90e15731c2 | ||
|
|
15d2415179 | ||
|
|
6fbb069352 | ||
|
|
6e1db823d4 | ||
|
|
3530a4f476 | ||
|
|
35580fb7e0 | ||
|
|
02c309b18f | ||
|
|
5b2e2a3ad4 | ||
|
|
a8d29d5c06 | ||
|
|
66f3a6a48b | ||
|
|
96c27a7267 | ||
|
|
f3928de7da | ||
|
|
e2487a4ec0 | ||
|
|
c238ab9eaf | ||
|
|
9b77ddaf15 | ||
|
|
40adb9dc90 | ||
|
|
42f7ab9e8d | ||
|
|
e19b70ef19 | ||
|
|
4297271bd9 | ||
|
|
120525c360 | ||
|
|
2efb46f050 | ||
|
|
df0f06dd22 | ||
|
|
5ce0415f65 | ||
|
|
c7c97dcc85 | ||
|
|
40def9f973 | ||
|
|
2fdc4b912e | ||
|
|
cdd92dcc7a | ||
|
|
064e56fdb8 | ||
|
|
6e99a67f24 | ||
|
|
f88ef0aeae | ||
|
|
5d3a93ae23 | ||
|
|
92d3038d21 | ||
|
|
4cda2e7daf | ||
|
|
f8fcc6fdba | ||
|
|
421b7c7d86 | ||
|
|
7281251572 | ||
|
|
f3d7439ff8 | ||
|
|
07b6bd1147 | ||
|
|
61bc17f2e3 | ||
|
|
070b37f34d | ||
|
|
2dd3567472 | ||
|
|
d8b05b2fca | ||
|
|
d87ceabcb2 | ||
|
|
31721739a5 | ||
|
|
196bbc622e | ||
|
|
dcd9d5f46b | ||
|
|
43e0b6f68a | ||
|
|
9d88dfc17e | ||
|
|
5a9bda6657 | ||
|
|
3506ef2020 | ||
|
|
05fd5b6e2a | ||
|
|
0d7c5e3711 | ||
|
|
53a4a84146 | ||
|
|
e2a40ccc71 | ||
|
|
26ccb8c391 | ||
|
|
c2c8c9bc3a | ||
|
|
4b287f03a0 | ||
|
|
da6ec0315f | ||
|
|
4f47141363 | ||
|
|
ad8fe50391 | ||
|
|
3d9c59ece6 | ||
|
|
f9c32195d1 | ||
|
|
993a380ab0 | ||
|
|
61612729ad | ||
|
|
5e1cfedfac | ||
|
|
fbceb97369 | ||
|
|
737483fd6f | ||
|
|
bf477f0a41 | ||
|
|
e9396960f1 | ||
|
|
5fb0982269 | ||
|
|
b480a16c41 | ||
|
|
91084d8cde | ||
|
|
6a8312f47a | ||
|
|
56c74df0f6 | ||
|
|
b9c75ff5f8 | ||
|
|
d1d30eebf7 | ||
|
|
f19790a3c3 | ||
|
|
efc56e7729 | ||
|
|
d322b090ea | ||
|
|
6c9ed28d32 | ||
|
|
a41a33904b | ||
|
|
2a490bd152 | ||
|
|
df4a5c3e56 | ||
|
|
107f6e4caa | ||
|
|
0c95950c86 | ||
|
|
56632a9d01 | ||
|
|
5cf4e27dc0 | ||
|
|
135dcb4677 | ||
|
|
1a2b604135 | ||
|
|
b8018f3539 | ||
|
|
a1570d3b3a | ||
|
|
462d43ae07 | ||
|
|
e8457d9e6a | ||
|
|
a3bfdbc868 | ||
|
|
caa3602994 | ||
|
|
1221915be7 | ||
|
|
5d708111e8 | ||
|
|
5e54d931d7 | ||
|
|
b879a049d3 | ||
|
|
a02d730c17 | ||
|
|
7d7dda586d | ||
|
|
dc8496a9d5 | ||
|
|
355a64c2f2 | ||
|
|
26e1ad823d | ||
|
|
80979e6504 | ||
|
|
02ee17da26 | ||
|
|
929840e26f | ||
|
|
62baf2e607 | ||
|
|
98a4031b32 | ||
|
|
79b399cbbe | ||
|
|
997029f12c | ||
|
|
76b82e5f5b | ||
|
|
04bb53edb7 | ||
|
|
7890623673 | ||
|
|
c41d379f41 | ||
|
|
c1885c587f | ||
|
|
9ca3be0b9d | ||
|
|
7f4dcdb9f8 | ||
|
|
3398cf6f99 | ||
|
|
7cf24aa080 | ||
|
|
bd8719bd9f | ||
|
|
fcf933885e | ||
|
|
dc8f8aff78 | ||
|
|
e1e5704dbc | ||
|
|
574f9d5438 | ||
|
|
7449a44dab | ||
|
|
e5a227939a | ||
|
|
2aa13cc3e6 | ||
|
|
7129665d5e | ||
|
|
c746311264 | ||
|
|
d10b78ef67 | ||
|
|
bc5ed67944 | ||
|
|
8161a1729c | ||
|
|
fa1291ebdd | ||
|
|
c896791033 | ||
|
|
b1948e330c | ||
|
|
717903744b | ||
|
|
8e21d647a3 | ||
|
|
fe380760fa | ||
|
|
bc005b669a | ||
|
|
98cb653713 | ||
|
|
eaec1a1310 | ||
|
|
26c3adc02a | ||
|
|
e41ea138ed | ||
|
|
d8ee40f38e | ||
|
|
665e6fd0fe | ||
|
|
ed006a6e55 | ||
|
|
ecbe33ba1f | ||
|
|
a8e8c3347e | ||
|
|
365ab89ff1 | ||
|
|
a4a595e66b | ||
|
|
23db1b508d | ||
|
|
cca331590e | ||
|
|
eb9a3a401e | ||
|
|
7a5394fb8d | ||
|
|
8fbfe405eb | ||
|
|
5f1d70f34b | ||
|
|
0df7b0ae2e | ||
|
|
3be073bf3f | ||
|
|
87f60d2950 | ||
|
|
4f9bc8042e | ||
|
|
dcdb16390d | ||
|
|
b233fcb091 | ||
|
|
b23b2beba2 | ||
|
|
a532fccce9 | ||
|
|
63c7b1c87f | ||
|
|
9ae9f77eba | ||
|
|
ab7c0a5de4 | ||
|
|
a342476366 | ||
|
|
f06c06cc02 | ||
|
|
3cf272152f | ||
|
|
155cc70c08 | ||
|
|
97d47f088b | ||
|
|
747596d86c | ||
|
|
7a90f40565 | ||
|
|
69e8b3b6da | ||
|
|
88685c2837 | ||
|
|
a54e766b19 | ||
|
|
5fed3ac046 | ||
|
|
4e7c08713b | ||
|
|
352fd0ce52 | ||
|
|
5dbba6d246 | ||
|
|
bfcf2223c9 | ||
|
|
a204d31fcb | ||
|
|
e03b3ec9ac | ||
|
|
7c299f595a | ||
|
|
a52c7e0b0f | ||
|
|
fcdb2c7f82 | ||
|
|
e43516dbf4 | ||
|
|
5651b59e2c | ||
|
|
1f8e502eb1 | ||
|
|
e141e18936 | ||
|
|
c95a2ce4db | ||
|
|
083a7345ed | ||
|
|
b881c81736 | ||
|
|
805a45b94e | ||
|
|
770a5c92ac | ||
|
|
7b73186210 | ||
|
|
a9cb3be6d4 | ||
|
|
6930609507 | ||
|
|
c30c7f0e2e | ||
|
|
1c6db0c8e6 | ||
|
|
2d9cdf729b | ||
|
|
e0036f3aa6 | ||
|
|
661263ff5f | ||
|
|
d3fb4271f1 | ||
|
|
1d93c88237 | ||
|
|
c96cd3695b | ||
|
|
d64bf8f6d5 | ||
|
|
6a90d25915 | ||
|
|
a66f7e5e35 | ||
|
|
eb4d6a2bfd | ||
|
|
4ccd3ec9d7 | ||
|
|
cf58f3907a | ||
|
|
17fd5c8867 | ||
|
|
1777a6fd9a | ||
|
|
7044bc0f02 | ||
|
|
d47dad90c0 | ||
|
|
851ec98b28 | ||
|
|
de4026e86d | ||
|
|
42ac79b1ed | ||
|
|
fef90ef5bd | ||
|
|
9a84b0cccc | ||
|
|
7aba72df4a | ||
|
|
1bd2a1816b | ||
|
|
68c844cc52 | ||
|
|
af31149d88 | ||
|
|
1b1dd880a2 | ||
|
|
dbea8f6f92 | ||
|
|
a56e7dd55d | ||
|
|
97bc5d4801 | ||
|
|
9e9ee7c728 | ||
|
|
f90ae398db | ||
|
|
b19107392d | ||
|
|
4b129583de | ||
|
|
6d9618638c | ||
|
|
a189c8702c | ||
|
|
2e893a3ca2 | ||
|
|
969731b074 | ||
|
|
9a60d63c7d | ||
|
|
8f1eaf4358 | ||
|
|
ae7d83f1fa | ||
|
|
3f1d6e5ef6 | ||
|
|
4df0825337 | ||
|
|
e8fbf4f1ab | ||
|
|
98d99bfe4d | ||
|
|
3a24dc48f9 | ||
|
|
5dd0b5f015 | ||
|
|
835e1f316b | ||
|
|
814ba61691 | ||
|
|
af33c56591 | ||
|
|
f465bedbd3 | ||
|
|
4eb9e842b1 | ||
|
|
a47fefad6c | ||
|
|
4fcb3c563f | ||
|
|
3b34c3eb5d | ||
|
|
c9dabf21a9 | ||
|
|
241a0cf38c | ||
|
|
0cfda21d31 | ||
|
|
1b051e200c | ||
|
|
0f83d5e73e | ||
|
|
10f8769c87 | ||
|
|
1de6db6366 | ||
|
|
caaca91df5 | ||
|
|
a2b789c71b | ||
|
|
534f10cc2b | ||
|
|
bbb69cddeb | ||
|
|
0abc88de15 | ||
|
|
0e711c0577 | ||
|
|
8d325645c0 | ||
|
|
5b41d193b5 | ||
|
|
12d3ee310f | ||
|
|
f60da1d3d9 | ||
|
|
6c067d60ca | ||
|
|
9676b7087a | ||
|
|
d40dce94a7 | ||
|
|
051513a202 | ||
|
|
e56219f73c | ||
|
|
c5bdc08150 | ||
|
|
46406d757e | ||
|
|
bf20f939a9 | ||
|
|
b203dfdd2e | ||
|
|
b86a26fec5 | ||
|
|
fd9677e060 | ||
|
|
20aae00bee | ||
|
|
6c75c4ebd3 | ||
|
|
d549c92e3c | ||
|
|
1cb4020632 | ||
|
|
35cafc3460 | ||
|
|
2d7f928207 | ||
|
|
881bee9fc9 | ||
|
|
3e74787ecb | ||
|
|
dcddae2cfd | ||
|
|
2074cda08a | ||
|
|
94f27781a8 | ||
|
|
3871563762 | ||
|
|
17b92cd315 | ||
|
|
6d86ac51dc | ||
|
|
9f2aae1f6b | ||
|
|
b8acf3e04e | ||
|
|
7cec95c2f3 | ||
|
|
f464cce955 | ||
|
|
067a45d815 | ||
|
|
3ee5b827b9 | ||
|
|
1e6d17e419 | ||
|
|
04e8bdde91 | ||
|
|
d683b57b2e | ||
|
|
7216ecea64 | ||
|
|
f39e904d6e | ||
|
|
426c86cbcf | ||
|
|
dc5751c0cd | ||
|
|
0a2b212b0b | ||
|
|
ce0206c4e3 | ||
|
|
ca12430835 | ||
|
|
700a0e062a | ||
|
|
a28c372c48 | ||
|
|
730054f910 | ||
|
|
d2d7f3316f | ||
|
|
36a7b206d8 | ||
|
|
0b4e2d9532 | ||
|
|
4ca30a13cd | ||
|
|
7d774f1173 | ||
|
|
4eba799515 | ||
|
|
b7b8a49e82 | ||
|
|
ebb9aa206e | ||
|
|
8103d921d7 | ||
|
|
0471c9b2b1 | ||
|
|
10a6a49fd5 | ||
|
|
7adc35c12f | ||
|
|
dd35a5ecf6 | ||
|
|
022dfe65c5 | ||
|
|
6a6fb48508 | ||
|
|
0cff0e534b | ||
|
|
21d0f0b8a4 | ||
|
|
b377bda982 | ||
|
|
ca4255ac63 | ||
|
|
00ca47aef2 | ||
|
|
208bee2b87 | ||
|
|
649a49f382 | ||
|
|
accbcb3ee5 | ||
|
|
0b55a56039 | ||
|
|
160b2a57bd | ||
|
|
e79005a535 | ||
|
|
a51fab2eed | ||
|
|
7e36744551 | ||
|
|
4e69151c4a | ||
|
|
3c7099fc3a | ||
|
|
9c83d0f4cc | ||
|
|
419f3cf02a | ||
|
|
c50ed34776 | ||
|
|
dd8bd30324 | ||
|
|
4d172d8b02 | ||
|
|
5a95677119 | ||
|
|
cdc924b8e5 | ||
|
|
0dd183b637 | ||
|
|
819201a5b2 | ||
|
|
fb681af44b | ||
|
|
fe18bfc8d4 | ||
|
|
830ce73dd5 | ||
|
|
f35837bd7d | ||
|
|
7b6ec9ab2f | ||
|
|
4ce9ffa942 | ||
|
|
ce2a371498 | ||
|
|
55c184bf68 | ||
|
|
57abf4807f |
@@ -97,6 +97,7 @@ body{padding-bottom:26px}
|
||||
<a href="/all-ia-hub.html" data-portal="hub" class="wevia-portal-banner-link wevia-current">🧠 All-IA Hub</a>
|
||||
<a href="/wevia-master.html" data-portal="master" class="wevia-portal-banner-link">🤖 WEVIA Master</a>
|
||||
<a href="/wevia-orchestrator.html" data-portal="arena" class="wevia-portal-banner-link">🎭 Arena Orchestrator</a>
|
||||
<a href="/wevia-chat-v2.html" data-portal="chatv2" class="wevia-portal-banner-link">Chat V2</a>
|
||||
<a href="/weval-technology-platform.html" data-portal="wtp" class="wevia-portal-banner-link">🧭 WTP Hub</a>
|
||||
<span class="wevia-portal-badge-wave">WAVE 221</span>
|
||||
</div>
|
||||
@@ -1335,5 +1336,33 @@ setInterval(refreshStats,60000);
|
||||
</div>
|
||||
<script>(function(){var p=window.location.pathname;var pub=["/","/index.html","/wevia.html","/wevia-widget.html","/enterprise-model.html","/wevia","/login","/register.html","/agents-archi.html","/wevia-meeting-rooms.html","/director-center.html","/director-chat.html","/l99-brain.html","/agents-fleet.html","/value-streaming.html","/architecture.html","/openclaw.html","/l99-saas.html","/admin-saas.html","/agents-goodjob.html","/ai-benchmark.html","/oss-discovery.html","/paperclip.html","/agents-3d.html","/agents-alive.html","/agents-enterprise.html","/agents-hd.html","/agents-iso3d.html","/agents-sim.html","/agents-valuechain.html","/avatar-picker.html"];var isPub=pub.indexOf(p)>=0||p.indexOf("/products/")===0||p.indexOf("/solutions/")===0||p.indexOf("/blog/")===0||p.indexOf("/service/")===0||p.indexOf("/marketplace")===0||p.indexOf("/contact")===0||p.indexOf("/tarifs")===0||p.indexOf("/news")===0;if(isPub||document.getElementById("weval-gl"))return;var a=document.createElement("a");a.id="weval-gl";a.href="/logout";a.textContent="Logout";a.style.cssText="position:fixed;top:10px;right:12px;z-index:99990;padding:5px 10px;background:rgba(30,30,50,0.7);color:rgba(200,210,230,0.8);border:1px solid rgba(100,100,140,0.3);border-radius:6px;font:500 11px system-ui,sans-serif;text-decoration:none;opacity:0.6;cursor:pointer;backdrop-filter:blur(6px);transition:all .15s";a.onmouseover=function(){this.style.opacity="1";this.style.background="rgba(239,68,68,0.85)";this.style.color="white"};a.onmouseout=function(){this.style.opacity="0.6";this.style.background="rgba(30,30,50,0.7)";this.style.color="rgba(200,210,230,0.8)"};document.body.appendChild(a)})()</script><script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||||
<script src="/api/weval-feature-tracker.js" defer></script>
|
||||
<script src="/api/ambre-universal-chat.js" defer></script>
|
||||
|
||||
<!-- WAVE 265 · Factory pill cross-page (injected, position mesurée zéro overlap) -->
|
||||
<a id="w265-factory-cross" href="/wevia-multiagent-dashboard.html" title="Factory Health Monitor (30 agents)"
|
||||
style="position:fixed;top:12px;left:12px;padding:6px 12px;border-radius:14px;background:linear-gradient(135deg,rgba(34,211,238,.2),rgba(168,85,247,.15));border:1px solid rgba(34,211,238,.4);color:#67e8f9;font-size:11px;font-weight:700;text-decoration:none;display:inline-flex;align-items:center;gap:6px;z-index:9999;backdrop-filter:blur(10px);box-shadow:0 2px 8px rgba(0,0,0,.4)">
|
||||
<span>🏭</span>
|
||||
<span id="w265-factory-txt">Factory: ...</span>
|
||||
</a>
|
||||
<script>
|
||||
/* w265 Factory auto-load */
|
||||
(function(){
|
||||
async function refresh(){
|
||||
try {
|
||||
const r = await fetch('/api/wevia-v83-business-kpi.php?action=summary', {cache:'no-store'}).then(r=>r.json()).catch(()=>null);
|
||||
const el = document.getElementById('w265-factory-txt');
|
||||
if(el && r && r.summary){
|
||||
const s = r.summary;
|
||||
const pct = s.data_completeness_pct || 0;
|
||||
el.textContent = `Factory: ${pct}% (${s.ok || 0}/${s.total_kpis || 0})`;
|
||||
}
|
||||
} catch(e){ console.log('[w265] factory check err', e); }
|
||||
}
|
||||
refresh();
|
||||
setInterval(refresh, 60000);
|
||||
})();
|
||||
</script>
|
||||
<!-- /WAVE 265 Factory pill cross-page -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -15,7 +15,7 @@ $actualites = [
|
||||
"status" => "published",
|
||||
"featured" => true,
|
||||
"views" => 234,
|
||||
"image" => "",
|
||||
"image" => "/uploads/actualites/img-wevia-ia.jpg",
|
||||
"created_at" => "2026-03-11T10:00:00.000Z"
|
||||
],
|
||||
[
|
||||
@@ -28,7 +28,7 @@ $actualites = [
|
||||
"status" => "published",
|
||||
"featured" => true,
|
||||
"views" => 187,
|
||||
"image" => "",
|
||||
"image" => "/uploads/actualites/img-huawei-al.jpg",
|
||||
"created_at" => "2026-03-10T10:00:00.000Z"
|
||||
],
|
||||
[
|
||||
@@ -41,7 +41,7 @@ $actualites = [
|
||||
"status" => "published",
|
||||
"featured" => true,
|
||||
"views" => 312,
|
||||
"image" => "",
|
||||
"image" => "/uploads/actualites/img-ai-factory.jpg",
|
||||
"created_at" => "2026-03-08T10:00:00.000Z"
|
||||
],
|
||||
[
|
||||
@@ -54,7 +54,7 @@ $actualites = [
|
||||
"status" => "published",
|
||||
"featured" => false,
|
||||
"views" => 156,
|
||||
"image" => "",
|
||||
"image" => "/uploads/actualites/img-sap-cloud.jpg",
|
||||
"created_at" => "2026-02-25T10:00:00.000Z"
|
||||
],
|
||||
[
|
||||
@@ -67,7 +67,7 @@ $actualites = [
|
||||
"status" => "published",
|
||||
"featured" => false,
|
||||
"views" => 98,
|
||||
"image" => "",
|
||||
"image" => "/uploads/actualites/img-analytics.jpg",
|
||||
"created_at" => "2026-02-20T10:00:00.000Z"
|
||||
],
|
||||
[
|
||||
@@ -80,7 +80,7 @@ $actualites = [
|
||||
"status" => "published",
|
||||
"featured" => false,
|
||||
"views" => 145,
|
||||
"image" => "",
|
||||
"image" => "/uploads/actualites/handshake-deal.jpg",
|
||||
"created_at" => "2026-02-15T10:00:00.000Z"
|
||||
],
|
||||
[
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"agent": "V41_Activation_Campaign",
|
||||
"ts": "2026-04-21T10:00:01+02:00",
|
||||
"unique_ips_24h_estimate": 17,
|
||||
"chat_queries_24h": 16,
|
||||
"dau_real_estimate": 5,
|
||||
"ts": "2026-04-23T10:00:02+02:00",
|
||||
"unique_ips_24h_estimate": 81,
|
||||
"chat_queries_24h": 5,
|
||||
"dau_real_estimate": 27,
|
||||
"target_trials_week": 5,
|
||||
"activation_targets": ["Kaouther_Najar_Ethica","Olga_Vistex","Ray_Huawei","5_prospects_pharma_banque"],
|
||||
"emails_to_send_this_week": 5,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V41_CSM_Daily",
|
||||
"ts": "2026-04-21T09:00:02+02:00",
|
||||
"ts": "2026-04-23T09:00:02+02:00",
|
||||
"customers_active": ["Vistex","Ethica","Huawei","Confluent"],
|
||||
"customers_count": 4,
|
||||
"ethica_last_activity": "none",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"agent": "V41_Disk_Monitor",
|
||||
"ts": "2026-04-22T04:30:02+02:00",
|
||||
"disk_pct": 85,
|
||||
"disk_free_gb": 22,
|
||||
"ts": "2026-04-23T19:30:01+02:00",
|
||||
"disk_pct": 86,
|
||||
"disk_free_gb": 21,
|
||||
"growth_per_day_gb": 1.5,
|
||||
"runway_days": 14,
|
||||
"alert": "WARN_runway_under_30d",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V41_Risk_Escalation",
|
||||
"ts": "2026-04-22T04:45:03+02:00",
|
||||
"ts": "2026-04-23T19:30:03+02:00",
|
||||
"dg_alerts_active": 7,
|
||||
"wevia_life_stats_preview": "{
|
||||
"ok": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V61_Ethica_Countdown",
|
||||
"ts": "2026-04-21T09:00:01+02:00",
|
||||
"ts": "2026-04-23T09:00:01+02:00",
|
||||
"client": "Ethica Group",
|
||||
"contact": "Kaouther Najar",
|
||||
"contract": "renewal Q1 2026",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"routes": 446,
|
||||
"skills": 835,
|
||||
"wiki": 2066,
|
||||
"pages": 318,
|
||||
"apis": 252,
|
||||
"docker": 19,
|
||||
"wiki": 2334,
|
||||
"pages": 331,
|
||||
"apis": 255,
|
||||
"docker": 17,
|
||||
"proposals": [
|
||||
{
|
||||
"name": "Fix 16 APIs PHP 500",
|
||||
@@ -27,5 +27,5 @@
|
||||
"effort": "S"
|
||||
}
|
||||
],
|
||||
"timestamp": "2026-04-21 22:00"
|
||||
"timestamp": "2026-04-23 16:00"
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"timestamp": "2026-04-22 00:00",
|
||||
"timestamp": "2026-04-23 12:00",
|
||||
"analysis": {
|
||||
"existing_skills": 835,
|
||||
"missing": 15,
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"agent": "V41_Feature_Adoption_Tracker",
|
||||
"ts": "2026-04-22T04:00:02+02:00",
|
||||
"ts": "2026-04-23T19:00:02+02:00",
|
||||
"features_tracked": 15,
|
||||
"features_used_24h": 10,
|
||||
"adoption_pct": 66,
|
||||
"chat_queries_last_1k_log": 0,
|
||||
"wtp_views_last_1k_log": 1,
|
||||
"dg_views_last_1k_log": 0,
|
||||
"skill_runs_last_1k_log": 0,
|
||||
"features_used_24h": 13,
|
||||
"adoption_pct": 86,
|
||||
"chat_queries_last_1k_log": 5,
|
||||
"wtp_views_last_1k_log": 45,
|
||||
"dg_views_last_1k_log": 2,
|
||||
"skill_runs_last_1k_log": 1,
|
||||
"recommendation": "UX onboarding tour for unused features",
|
||||
"cron_schedule": "hourly",
|
||||
"root_cause_resolved": "feature_adoption_rate via usage tracking + onboarding signals"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V61_GitHub_PAT_Watcher",
|
||||
"ts": "2026-04-21T10:00:03+02:00",
|
||||
"ts": "2026-04-23T10:00:06+02:00",
|
||||
"pat_configured": false,
|
||||
"last_push_health": "OK",
|
||||
"remote_probe": "fatal: unable to get credential storage ",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V45_Leads_Sync",
|
||||
"ts": "2026-04-22T04:50:03+02:00",
|
||||
"ts": "2026-04-23T19:40:03+02:00",
|
||||
"paperclip_total": 48,
|
||||
"active_customer": 4,
|
||||
"warm_prospect": 5,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V61_LinkedIn_Sourcing",
|
||||
"ts": "2026-04-21T11:00:02+02:00",
|
||||
"ts": "2026-04-23T11:00:01+02:00",
|
||||
"icp_count": 39,
|
||||
"icp_source": "V46 39 ICP Pharma/Banque/Retail/Public Maghreb+MENA",
|
||||
"api_keys_configured": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V41_MQL_Scoring",
|
||||
"ts": "2026-04-22T04:00:04+02:00",
|
||||
"ts": "2026-04-23T19:00:04+02:00",
|
||||
"leads_total": 48,
|
||||
"mql_current": 16,
|
||||
"sql_current": 6,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V60_Nudge_Owner_Actions",
|
||||
"ts": "2026-04-22T00:00:02+02:00",
|
||||
"ts": "2026-04-23T16:00:01+02:00",
|
||||
"cron": "every_8_hours",
|
||||
"actions_pending_owner": {
|
||||
"emails_drafts_V45_to_send": {
|
||||
@@ -10,10 +10,10 @@
|
||||
"action": "Yacine envoie via Gmail ymahboub@weval-consulting.com"
|
||||
},
|
||||
"ethica_renewal_Q1": {
|
||||
"days_to_Q1_end": -22,
|
||||
"days_to_Q1_end": -23,
|
||||
"amount_keur": 280,
|
||||
"urgency": "CRITICAL",
|
||||
"action": "Close contrat avec Kaouther Najar avant -22 jours"
|
||||
"action": "Close contrat avec Kaouther Najar avant -23 jours"
|
||||
},
|
||||
"sourcing_39_emails_linkedin": {
|
||||
"count": 39,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"ts": "2026-04-22T03:00:03.853778",
|
||||
"ts": "2026-04-23T03:00:04.220450",
|
||||
"v2_entries": 775,
|
||||
"missing_count": 1,
|
||||
"missing_agents": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V54_Risk_Monitor_Live",
|
||||
"ts": "2026-04-22T04:30:03+02:00",
|
||||
"ts": "2026-04-23T19:30:04+02:00",
|
||||
"critical_risks": {
|
||||
"RW01_pipeline_vide": {
|
||||
"pipeline_keur": 0,
|
||||
@@ -9,20 +9,20 @@
|
||||
"trend": "mitigation_V42_V45_active"
|
||||
},
|
||||
"RW02_dependance_ethica": {
|
||||
"active_clients": 4,
|
||||
"concentration_top_client_pct": 25,
|
||||
"residual_risk_pct": 25,
|
||||
"active_clients": 1,
|
||||
"concentration_top_client_pct": 100,
|
||||
"residual_risk_pct": 100,
|
||||
"trend": "diversification_V46_ICP_39_ongoing"
|
||||
},
|
||||
"RW04_revenue_saas": {
|
||||
"mrr_current_keur": 2,
|
||||
"saas_pct_of_target": 4,
|
||||
"residual_risk_pct": 96,
|
||||
"mrr_current_keur": 0,
|
||||
"saas_pct_of_target": 0,
|
||||
"residual_risk_pct": 100,
|
||||
"trend": "Ethica_renewal_Q1_critical"
|
||||
},
|
||||
"RW12_burnout": {
|
||||
"agents_cron_active": 15,
|
||||
"load_5min": "7.72",
|
||||
"load_5min": "17.22",
|
||||
"automation_coverage_pct": 70,
|
||||
"residual_risk_pct": 60,
|
||||
"trend": "V52_goldratt_options_active"
|
||||
|
||||
@@ -1,122 +1,107 @@
|
||||
{
|
||||
"timestamp": "2026-04-22 04:00",
|
||||
"timestamp": "2026-04-23 18:00",
|
||||
"sections": {
|
||||
"servers": {
|
||||
"S204": {
|
||||
"docker": 19,
|
||||
"disk": "85%",
|
||||
"ram": "13Gi/30Gi",
|
||||
"load": "13.04",
|
||||
"uptime": "up 1 week, 16 hours, 8 minutes"
|
||||
"docker": 17,
|
||||
"disk": "86%",
|
||||
"ram": "16Gi/30Gi",
|
||||
"load": "19.38",
|
||||
"uptime": "up 1 week, 2 days, 6 hours, 8 minutes"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"count": 20,
|
||||
"count": 17,
|
||||
"containers": [
|
||||
{
|
||||
"name": "weval-docuseal",
|
||||
"status": "Up Less than a second",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "loki",
|
||||
"status": "Up 5 days",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "listmonk",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "plausible-plausible-1",
|
||||
"status": "Up 4 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "plausible-plausible-db-1",
|
||||
"status": "Up 4 days",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "plausible-plausible-events-db-1",
|
||||
"status": "Up 4 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "n8n-docker-n8n-1",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "mattermost-docker-mm-db-1",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "mattermost-docker-mattermost-1",
|
||||
"status": "Up 5 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "twenty",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "twenty-redis",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "langfuse",
|
||||
"status": "Up 6 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "redis-weval",
|
||||
"name": "n8n-docker-n8n-1",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "gitea",
|
||||
"name": "mattermost-docker-mm-db-1",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "node-exporter",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "prometheus",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "searxng",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "uptime-kuma",
|
||||
"status": "Up 2 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "vaultwarden",
|
||||
"name": "mattermost-docker-mattermost-1",
|
||||
"status": "Up 7 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "qdrant",
|
||||
"name": "twenty",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "twenty-redis",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "langfuse",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "redis-weval",
|
||||
"status": "Up 9 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "gitea",
|
||||
"status": "Up 9 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "node-exporter",
|
||||
"status": "Up 9 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "prometheus",
|
||||
"status": "Up 9 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "searxng",
|
||||
"status": "Up 9 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "uptime-kuma",
|
||||
"status": "Up 3 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "vaultwarden",
|
||||
"status": "Up 9 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "qdrant",
|
||||
"status": "Up 9 days",
|
||||
"ports": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"apis": {
|
||||
"count": 273,
|
||||
"count": 276,
|
||||
"files": [
|
||||
"wevia-stream-sovereign.php",
|
||||
"wevia-pending-loader.php",
|
||||
@@ -180,6 +165,7 @@
|
||||
"wevia-agent-chef.php",
|
||||
"wevia-agentic.php",
|
||||
"wevia-arena-engine.php",
|
||||
"wevia-factory.php",
|
||||
"wevia-brain.php",
|
||||
"wevia-capabilities-ext.php",
|
||||
"wevia-sovereign-heal-intent.php",
|
||||
@@ -223,6 +209,7 @@
|
||||
"wevia-vault-llm.php",
|
||||
"wevia-tool-test.php",
|
||||
"wevia-v74-intents-include.php",
|
||||
"wevia-chat-memory.php",
|
||||
"wevia-self-diagnostic-intent.php",
|
||||
"wevia-control-kpis.php",
|
||||
"wevia-test-email-intent.php",
|
||||
@@ -253,6 +240,7 @@
|
||||
"wevia-opus-intents.php",
|
||||
"wevia-decisions-api.php",
|
||||
"wevia-db-stats.php",
|
||||
"wevia-chat-v2-direct.php",
|
||||
"wevia-master-dispatch.php",
|
||||
"wevia-api-bridge.php",
|
||||
"wevia-vault-git-intents.php",
|
||||
@@ -450,7 +438,7 @@
|
||||
]
|
||||
},
|
||||
"qdrant": {
|
||||
"total": 22105,
|
||||
"total": 22123,
|
||||
"collections": {
|
||||
"weval_skills": 19089,
|
||||
"wevia_graph": 3,
|
||||
@@ -465,7 +453,7 @@
|
||||
"kb_bpmn_patterns": 7,
|
||||
"kb_dmaic_playbooks": 7,
|
||||
"kb_wevads_deliv": 6,
|
||||
"wevia_memory_768": 82,
|
||||
"wevia_memory_768": 100,
|
||||
"wevia_kb_768": 255,
|
||||
"weval_agents_registry": 50,
|
||||
"wevia_kb": 386,
|
||||
@@ -486,16 +474,16 @@
|
||||
]
|
||||
},
|
||||
"pages": {
|
||||
"count": 324
|
||||
"count": 331
|
||||
},
|
||||
"opt_tools": {
|
||||
"count": 95
|
||||
"count": 98
|
||||
},
|
||||
"dataset": {
|
||||
"pairs": 5751
|
||||
},
|
||||
"wiki": {
|
||||
"entries": 2123
|
||||
"entries": 2334
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"generated_at": "2026-04-22T00:00:03.159161",
|
||||
"generated_at": "2026-04-23T18:00:04.682375",
|
||||
"agent_version": "V69_enhanced",
|
||||
"pages_scanned": 9,
|
||||
"fixed_elements_checked": 19,
|
||||
"fixed_elements_checked": 23,
|
||||
"issues_count": 5,
|
||||
"status": "CRITICAL",
|
||||
"doctrine_61": "bottom-right reserved for chat WEVIA only",
|
||||
"issues": [
|
||||
{
|
||||
"page": "weval-technology-platform.html",
|
||||
"element": "opus-orphans-count-text",
|
||||
"type": "inline",
|
||||
"page": "wevia-widget.html",
|
||||
"element": "#opus-pattern-badge",
|
||||
"type": "css_rule",
|
||||
"corner": "bottom-right",
|
||||
"z": 9997,
|
||||
"z": 99990,
|
||||
"severity": "HIGH"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"timestamp": "2026-04-21T22:00:06+00:00",
|
||||
"compute_ms": 4023,
|
||||
"timestamp": "2026-04-23T16:00:07+00:00",
|
||||
"compute_ms": 4284,
|
||||
"metrics": {
|
||||
"agents": 0,
|
||||
"agents_hierarchy": 0,
|
||||
@@ -13,31 +13,31 @@
|
||||
"oss_tools": 765,
|
||||
"oss_skills": 734,
|
||||
"oss_tests": 765,
|
||||
"docker": 20,
|
||||
"docker": 17,
|
||||
"ollama_models": 7,
|
||||
"git_repos": 38,
|
||||
"providers": [
|
||||
{
|
||||
"name": "Cerebras",
|
||||
"latency_ms": 968,
|
||||
"latency_ms": 588,
|
||||
"status": "up"
|
||||
},
|
||||
{
|
||||
"name": "Groq",
|
||||
"latency_ms": 1001,
|
||||
"latency_ms": 428,
|
||||
"status": "up"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scores": {
|
||||
"combined": 75,
|
||||
"infra": 57,
|
||||
"infra": 52,
|
||||
"ecosystem": 100,
|
||||
"agents": 0,
|
||||
"skills": 100,
|
||||
"nonreg": 100,
|
||||
"oss": 100,
|
||||
"docker": 100,
|
||||
"docker": 85,
|
||||
"providers": 72,
|
||||
"hierarchy": 0,
|
||||
"instructions": 100
|
||||
@@ -45,7 +45,7 @@
|
||||
"leaderboard": [
|
||||
{
|
||||
"name": "WEVAL_Ecosystem",
|
||||
"score": 80.7,
|
||||
"score": 80.2,
|
||||
"skills": 839,
|
||||
"agents": 0
|
||||
},
|
||||
@@ -61,7 +61,7 @@
|
||||
},
|
||||
{
|
||||
"name": "WEVAL_MiroFish",
|
||||
"score": 100,
|
||||
"score": 85,
|
||||
"type": "sovereign"
|
||||
},
|
||||
{
|
||||
|
||||
36
api/ambre-agents-check.php
Normal file
36
api/ambre-agents-check.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
// Check which endpoints need auth
|
||||
$endpoints = [
|
||||
"/api/wevia-master-api.php",
|
||||
"/api/wevia-autonomous.php",
|
||||
"/api/ambre-multiagent-parallel.php",
|
||||
"/api/ambre-session-chat.php",
|
||||
"/api/ambre-tool-pdf-premium.php",
|
||||
"/api/ambre-tool-mermaid.php",
|
||||
"/api/ambre-tool-web-search.php",
|
||||
"/api/wevia-safe-write.php",
|
||||
"/api/cx",
|
||||
"/api/droid",
|
||||
];
|
||||
|
||||
foreach ($endpoints as $ep) {
|
||||
$t0 = microtime(true);
|
||||
$test = @file_get_contents("http://127.0.0.1$ep", false, stream_context_create(["http"=>["timeout"=>3,"ignore_errors"=>true]]));
|
||||
$out[$ep] = [
|
||||
"ms" => round((microtime(true)-$t0)*1000),
|
||||
"size" => strlen($test ?: ""),
|
||||
"first_50" => substr($test ?: "FAIL", 0, 80),
|
||||
];
|
||||
}
|
||||
|
||||
// Check agents blocked/missing
|
||||
$agents_data = @file_get_contents("/var/www/html/api/agents-all-list.json") ?: @file_get_contents("/var/www/html/api/agents.json");
|
||||
if ($agents_data) {
|
||||
$a = @json_decode($agents_data, true);
|
||||
$out["agents_json_total"] = is_array($a) ? count($a) : 0;
|
||||
}
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
122
api/ambre-agents-manifest.php
Normal file
122
api/ambre-agents-manifest.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-agents-manifest.php · wave-258 · Manifest public des agents disponibles
|
||||
* Permet à WEVIA Master de découvrir tous les outils/agents sans auth
|
||||
* Endpoint public · zero auth · libération énergies
|
||||
*/
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
|
||||
$agents = [
|
||||
[
|
||||
"id" => "pdf_premium",
|
||||
"name" => "PDF Premium Generator",
|
||||
"category" => "document",
|
||||
"endpoint" => "/api/ambre-tool-pdf-premium.php",
|
||||
"method" => "POST",
|
||||
"payload" => ["topic" => "string", "lang" => "fr|en|ar"],
|
||||
"auth" => "none",
|
||||
"avg_ms" => 2700,
|
||||
"trigger_keywords" => ["pdf", "rapport", "document pro", "premium"],
|
||||
"output" => "url PDF + metadata",
|
||||
"engine" => "LLM + Chromium",
|
||||
],
|
||||
[
|
||||
"id" => "mermaid_rag",
|
||||
"name" => "Mermaid Diagram RAG",
|
||||
"category" => "visualization",
|
||||
"endpoint" => "/api/ambre-tool-mermaid.php",
|
||||
"method" => "POST",
|
||||
"payload" => ["topic" => "string"],
|
||||
"auth" => "none",
|
||||
"avg_ms" => 400,
|
||||
"trigger_keywords" => ["schéma", "diagramme", "mermaid", "flowchart", "graph"],
|
||||
"output" => "code mermaid · source kb_reused OR llm",
|
||||
"engine" => "KB RAG + LLM fallback",
|
||||
],
|
||||
[
|
||||
"id" => "web_search",
|
||||
"name" => "Web Search",
|
||||
"category" => "research",
|
||||
"endpoint" => "/api/ambre-tool-web-search.php",
|
||||
"method" => "POST",
|
||||
"payload" => ["query" => "string"],
|
||||
"auth" => "none",
|
||||
"trigger_keywords" => ["cherche", "recherche", "search", "actualités", "news"],
|
||||
"output" => "answer + sources",
|
||||
],
|
||||
[
|
||||
"id" => "kb_search",
|
||||
"name" => "Knowledge Base Search",
|
||||
"category" => "research",
|
||||
"endpoint" => "/api/ambre-mermaid-learn.php",
|
||||
"method" => "POST",
|
||||
"payload" => ["action" => "search|list|stats", "query" => "string"],
|
||||
"auth" => "none",
|
||||
"avg_ms" => 50,
|
||||
"trigger_keywords" => ["sait", "as-tu déjà", "connu"],
|
||||
"output" => "entries JSON matching",
|
||||
],
|
||||
[
|
||||
"id" => "calc",
|
||||
"name" => "Calculator",
|
||||
"category" => "compute",
|
||||
"endpoint" => "/api/ambre-tool-calc.php",
|
||||
"method" => "POST",
|
||||
"payload" => ["expression" => "string"],
|
||||
"auth" => "none",
|
||||
"avg_ms" => 10,
|
||||
"trigger_keywords" => ["calcule", "combien", "somme", "multiplie"],
|
||||
"output" => "result numeric",
|
||||
],
|
||||
[
|
||||
"id" => "multiagent_parallel",
|
||||
"name" => "Multi-Agent Parallel Orchestrator",
|
||||
"category" => "orchestration",
|
||||
"endpoint" => "/api/ambre-multiagent-parallel.php",
|
||||
"method" => "POST",
|
||||
"payload" => ["goal" => "string", "max_agents" => "1-10"],
|
||||
"auth" => "none",
|
||||
"avg_ms" => 8000,
|
||||
"trigger_keywords" => ["analyse complete", "rapport complet", "compare avec", "multi-agent", "360"],
|
||||
"output" => "plan + results parallel + synthesis",
|
||||
"engine" => "Plan LLM → curl_multi → Reconcile LLM",
|
||||
"parallelism" => "TRUE (curl_multi_init)",
|
||||
],
|
||||
[
|
||||
"id" => "session_chat",
|
||||
"name" => "Session Chat with Memory",
|
||||
"category" => "conversation",
|
||||
"endpoint" => "/api/ambre-session-chat.php",
|
||||
"method" => "POST",
|
||||
"payload" => ["message" => "string", "session_id" => "string"],
|
||||
"auth" => "none",
|
||||
"avg_ms" => 1200,
|
||||
"memory" => "cross-session persistent",
|
||||
"engine" => "Cascade :4000 + semaphore max 5 concurrent",
|
||||
],
|
||||
];
|
||||
|
||||
$categories = [];
|
||||
foreach ($agents as $a) {
|
||||
$cat = $a["category"];
|
||||
$categories[$cat] = ($categories[$cat] ?? 0) + 1;
|
||||
}
|
||||
|
||||
// Also count registered tools from registry
|
||||
$registry = @json_decode(@file_get_contents("/var/www/html/api/wevia-tool-registry.json"), true);
|
||||
$registry_total = is_array($registry) ? count($registry["tools"] ?? []) : 0;
|
||||
|
||||
echo json_encode([
|
||||
"ok" => true,
|
||||
"version" => "wave-258",
|
||||
"ts" => date("c"),
|
||||
"agents" => $agents,
|
||||
"total" => count($agents),
|
||||
"categories" => $categories,
|
||||
"registry_tools_total" => $registry_total,
|
||||
"hub_dashboards" => 26,
|
||||
"auth_required" => "none — agents libres",
|
||||
"note" => "Tous ces endpoints sont libres d'accès pour l'autonomie maximale WEVIA",
|
||||
"invocation_pattern" => "curl POST endpoint + JSON payload → réponse JSON",
|
||||
], JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);
|
||||
15
api/ambre-check-wire.php
Normal file
15
api/ambre-check-wire.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
foreach (["wevia-master.html", "wevia-orchestrator.html", "director-chat.html", "l99-brain.html"] as $p) {
|
||||
$f = "/var/www/html/$p";
|
||||
if (!file_exists($f)) { $out[$p] = "missing"; continue; }
|
||||
$c = @file_get_contents($f);
|
||||
$out[$p] = [
|
||||
"size" => strlen($c),
|
||||
"widget" => substr_count($c, "ambre-universal-chat.js"),
|
||||
"last_body_pos" => strrpos($c, "</body>"),
|
||||
"ends_with" => substr(trim($c), -200),
|
||||
];
|
||||
}
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
@@ -19,6 +19,50 @@ $raw = file_get_contents("php://input");
|
||||
$in = json_decode($raw, true) ?: [];
|
||||
$msg = trim($in["message"] ?? "");
|
||||
if (!$msg) { sse("error", ["content"=>"No message"]); exit; }
|
||||
|
||||
// === V181 backend-public-guard · Yacine: pas de fuites chez clients externes ===
|
||||
$__v181_blocked = [
|
||||
"/^intents?_pool\b/i",
|
||||
"/^quelle\s+heure\s*$/i",
|
||||
"/^multiagent\s+parall[e\xc3\xa9\xc3\xa8]le/i",
|
||||
"/^orchestrate\s+parall[e\xc3\xa9\xc3\xa8]le/i",
|
||||
"/^cable\s+un?\s+intent/i",
|
||||
"/^nonreg\s*(?:score|status)?\s*$/i",
|
||||
"/^l99\s*(?:score|status)?\s*$/i",
|
||||
"/^6\s*sigma/i",
|
||||
"/^derniers?\s+commits?\s+git/i",
|
||||
"/^git\s+(?:log|commit|status)/i",
|
||||
"/\bWAVE-\d+/i",
|
||||
"/\bpool\s+total\b/i",
|
||||
"/^doctrines?\s+(?:wiki|list)/i",
|
||||
"/^load\s*$/i",
|
||||
"/\bwevia[-_.]?(?:master|orchestrator|autonomous)\b/i",
|
||||
"/^(?:ping|status|health)\s+(?:system|server|infra)/i",
|
||||
];
|
||||
$__v181_internal = false;
|
||||
$__v181_token = $_SERVER["HTTP_X_AGENT_TOKEN"] ?? "";
|
||||
$__v181_ref = $_SERVER["HTTP_REFERER"] ?? "";
|
||||
$__v181_expected_token = "";
|
||||
foreach (@file("/etc/weval/secrets.env") ?: [] as $__v181_line) {
|
||||
if (preg_match("/^AGENT_TOKEN=(.+)$/", trim($__v181_line), $__v181_mm)) {
|
||||
$__v181_expected_token = trim($__v181_mm[1], " \"\'"); break;
|
||||
}
|
||||
}
|
||||
if ($__v181_token && $__v181_expected_token && hash_equals($__v181_expected_token, $__v181_token)) $__v181_internal = true;
|
||||
if (stripos($__v181_ref, "/wevia-master.html") !== false || stripos($__v181_ref, "/wevia-master-") !== false || stripos($__v181_ref, "/proof-wave") !== false) $__v181_internal = true;
|
||||
if (!$__v181_internal) {
|
||||
foreach ($__v181_blocked as $__v181_pat) {
|
||||
if (@preg_match($__v181_pat, trim($msg))) {
|
||||
$__v181_greet = "Je suis WEVIA Assistant IA. Je peux vous aider avec la generation de documents (PDF, Word, Excel, PowerPoint), la creation d'images, de schemas et de code, les traductions, les recherches et les calculs. Que puis-je faire pour vous aujourd'hui ?";
|
||||
sse("start", ["session"=>"public", "query"=>$msg, "pattern"=>"guard", "engine"=>"WEVIA Assistant v1"]);
|
||||
sse("chunk", ["content"=>$__v181_greet, "index"=>0, "total"=>1]);
|
||||
sse("done", ["response"=>$__v181_greet, "provider"=>"wevia-public-guard-v1", "intent"=>"guard_redirect"]);
|
||||
@error_log("[V181-public-guard] blocked: " . substr($msg, 0, 80));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
// === END V181 ===
|
||||
$session_id = $in["session_id"] ?? ("wv-" . substr(md5(random_bytes(8)), 0, 10));
|
||||
|
||||
$pattern = "generic";
|
||||
@@ -175,7 +219,7 @@ foreach ($plan as $i => $step) {
|
||||
$d = @json_decode($raw_r, true);
|
||||
if ($d) {
|
||||
$final_response = $d["response"] ?? $d["content"] ?? "";
|
||||
if (preg_match("#https?://\S+?\.(?:pdf|docx|pptx|xlsx|svg|py|jsx)#", $final_response, $um)) {
|
||||
if (preg_match("#https?://\S+?\.(?:pdf|docx|pptx|xlsx|svg|py|jsx|jpg|jpeg|png|webp|gif)#", $final_response, $um)) {
|
||||
$final_file_url = $um[0];
|
||||
}
|
||||
}
|
||||
@@ -199,6 +243,6 @@ sse("done", [
|
||||
"response" => $final_response,
|
||||
"file_url" => $final_file_url,
|
||||
"pattern" => $pattern,
|
||||
"provider" => "ambre-claude-stream-v1",
|
||||
"provider" => "wevia-stream-v1",
|
||||
"intent" => $pattern . "_streamed",
|
||||
]);
|
||||
|
||||
116
api/ambre-confidential-shield.js
Normal file
116
api/ambre-confidential-shield.js
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* ambre-confidential-shield.js · wave-261
|
||||
* GARDE CONFIDENTIELLE : supprime tout badge/dock interne sur pages PUBLIQUES
|
||||
*
|
||||
* Usage: loadé en TÊTE sur /, /wevia.html, /wevia, /index.html
|
||||
*
|
||||
* ELEMENTS À MASQUER sur pages publiques :
|
||||
* - #opus-pattern-badge · Claude Pattern badge
|
||||
* - #opus-pattern-style · CSS associé
|
||||
* - #opus-udrill · drill menu fixed
|
||||
* - #opus-udrill-in · contenu drill
|
||||
* - #opus-dashboard-entry · dashboard hover
|
||||
* - #opus-dashboard-link · Dashboards link fixed
|
||||
* - #wtp-udock, #v130-xnav, #opus-xlinks · docks internes
|
||||
* - Tout élément avec text "WTP" + "Admin" + "Droid" dans un même conteneur fixed
|
||||
* - Tout lien vers /weval-technology-platform.html, /wevia-master.html, /all-ia-hub.html, etc. en position fixed
|
||||
*/
|
||||
(function(){
|
||||
'use strict';
|
||||
|
||||
// Public paths where shield is ACTIVE (block internal UI elements)
|
||||
var PUBLIC_PATHS = ['/', '/index.html', '/wevia-widget.html', '/wevia.html', '/wevia', '/consent.html', '/register.html', '/login'];
|
||||
var path = (location.pathname || '/').toLowerCase();
|
||||
var isPublic = PUBLIC_PATHS.indexOf(path) !== -1;
|
||||
if (!isPublic) return; // do nothing on private/auth pages
|
||||
|
||||
// IDs to HIDE on public pages (confidential internal UI)
|
||||
var CONFIDENTIAL_IDS = [
|
||||
'opus-pattern-badge', 'opus-pattern-style', 'opus-pattern-panel',
|
||||
'opus-pattern-modal', 'opus-pattern-box', 'opus-pattern-close', 'opus-pattern-input',
|
||||
'opus-pattern-bot', 'opus-pattern-output', 'opus-pattern-content',
|
||||
'opus-pattern-launch', 'opus-pattern-send',
|
||||
'opus-udrill', 'opus-udrill-in', 'opus-dashboard-entry', 'opus-dashboard-link',
|
||||
'wtp-udock', 'v130-xnav', 'opus-xlinks', 'wtp-sidebar',
|
||||
'opus-claude-pattern', 'opus-dashboards',
|
||||
'archi-meta-badge', 'v130-floating-dock',
|
||||
];
|
||||
|
||||
// Inject CSS that hides these IDs IMMEDIATELY (before any JS injects them)
|
||||
var css = document.createElement('style');
|
||||
css.id = 'ambre-confidential-shield';
|
||||
css.textContent = CONFIDENTIAL_IDS.map(function(id){return '#' + id;}).join(',') + '{display:none!important;visibility:hidden!important;pointer-events:none!important}';
|
||||
// Also hide any fixed element containing "Droid" + "Admin" text (the dock in Image 1)
|
||||
(document.head || document.documentElement).appendChild(css);
|
||||
|
||||
// MutationObserver to remove dynamically-injected leaks
|
||||
function scrubLeaks() {
|
||||
// Remove by id
|
||||
CONFIDENTIAL_IDS.forEach(function(id){
|
||||
var el = document.getElementById(id);
|
||||
if (el) el.remove();
|
||||
});
|
||||
|
||||
// Remove fixed elements with sensitive badges (WTP + IA Hub + Master + Droid + Admin)
|
||||
var fixedElements = document.querySelectorAll('div[style*="position: fixed"], div[style*="position:fixed"]');
|
||||
fixedElements.forEach(function(el){
|
||||
var txt = (el.innerText || '').toLowerCase();
|
||||
var matches = ['wtp', 'ia hub', 'master', 'orch', 'wevcode', 'arena', 'droid', 'admin', 'wevia engine']
|
||||
.filter(function(kw){ return txt.indexOf(kw) !== -1; }).length;
|
||||
if (matches >= 4) { // if 4+ internal keywords present → remove
|
||||
el.remove();
|
||||
}
|
||||
});
|
||||
|
||||
// Remove <a href="..."> fixed shortcuts to internal pages
|
||||
var privatePages = ['weval-technology-platform', 'wevia-master', 'all-ia-hub', 'wevia-orchestrator', 'wevcode', 'droid.html', 'admin-saas'];
|
||||
document.querySelectorAll('a[href]').forEach(function(a){
|
||||
var href = (a.getAttribute('href') || '').toLowerCase();
|
||||
var style = window.getComputedStyle(a);
|
||||
if (style.position === 'fixed' || (a.parentElement && window.getComputedStyle(a.parentElement).position === 'fixed')) {
|
||||
for (var i = 0; i < privatePages.length; i++) {
|
||||
if (href.indexOf(privatePages[i]) !== -1) {
|
||||
a.remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Run at DOM ready and on mutations
|
||||
if (document.readyState !== 'loading') scrubLeaks();
|
||||
else document.addEventListener('DOMContentLoaded', scrubLeaks);
|
||||
|
||||
// MutationObserver for post-load injections
|
||||
var mo = new MutationObserver(function(mutations){
|
||||
for (var i = 0; i < mutations.length; i++) {
|
||||
var m = mutations[i];
|
||||
if (m.addedNodes && m.addedNodes.length > 0) {
|
||||
scrubLeaks();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Start observing once body available
|
||||
function startObserver(){
|
||||
if (document.body) mo.observe(document.body, { childList: true, subtree: true });
|
||||
else setTimeout(startObserver, 100);
|
||||
}
|
||||
startObserver();
|
||||
|
||||
// Periodic sweep (catch late injections)
|
||||
setInterval(scrubLeaks, 2000);
|
||||
|
||||
// Also stop at 60s to save CPU
|
||||
setTimeout(function(){ try { mo.disconnect(); } catch(e){} }, 60000);
|
||||
|
||||
// Neutralize global opusPatternOpen function (prevents programmatic opening)
|
||||
try {
|
||||
Object.defineProperty(window, '__opusPatternOpen', { value: function(){}, writable: false, configurable: false });
|
||||
Object.defineProperty(window, '__opusPatternClose', { value: function(){}, writable: false, configurable: false });
|
||||
} catch(e) {}
|
||||
|
||||
console.log('[ambre-confidential-shield] active on public page: ' + path);
|
||||
})();
|
||||
5
api/ambre-ctx.php
Normal file
5
api/ambre-ctx.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$c = @file_get_contents("/var/www/html/wevia.html");
|
||||
echo "=== around 94630 (phase result) ===\n";
|
||||
echo substr($c, 94500, 1500);
|
||||
43
api/ambre-dock-fix.php
Normal file
43
api/ambre-dock-fix.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/wtp-unified-dock.js";
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
|
||||
// Add wevia-widget.html + all chatbot public pages to PUBLIC_PATHS
|
||||
$old = "var _AMBRE_PUBLIC_PATHS = ['/wevia.html', '/wevia', '/', '/index.html', '/consent.html', '/mirofish.html'];";
|
||||
$new = "var _AMBRE_PUBLIC_PATHS = ['/wevia.html', '/wevia', '/', '/index.html', '/consent.html', '/mirofish.html', '/wevia-widget.html', '/wevia-widget', '/register.html', '/register', '/login', '/login.html'];";
|
||||
|
||||
if (strpos($c, $old) === false) {
|
||||
echo json_encode(["error"=>"PUBLIC_PATHS pattern not found"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Also add iframe detection → if we are in an iframe on a public parent → skip dock
|
||||
$ext1 = " // === END AMBRE-V1-PUBLIC-GUARD ===";
|
||||
$ext2 = " // === END AMBRE-V1-PUBLIC-GUARD ===
|
||||
|
||||
// === AMBRE-V2-IFRAME-GUARD 2026-04-22 · skip dock if embedded in iframe (public widget context) ===
|
||||
try {
|
||||
if (window.self !== window.top) {
|
||||
// Running inside iframe - public widget context - DO NOT render dock
|
||||
return;
|
||||
}
|
||||
} catch(e) {
|
||||
// Cross-origin access error means we ARE in iframe - skip
|
||||
return;
|
||||
}
|
||||
// === END AMBRE-V2-IFRAME-GUARD ===";
|
||||
|
||||
$c = str_replace($old, $new, $c);
|
||||
$c = str_replace($ext1, $ext2, $c);
|
||||
|
||||
$backup = "/opt/wevads/vault/wtp-unified-dock.GOLD-" . date("Ymd-His") . "-wave262-widget-guard";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $c);
|
||||
|
||||
echo json_encode([
|
||||
"delta" => strlen($c) - $orig,
|
||||
"wrote" => $wrote,
|
||||
"backup" => basename($backup),
|
||||
]);
|
||||
14
api/ambre-dock-read.php
Normal file
14
api/ambre-dock-read.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$f = "/var/www/html/wtp-unified-dock.js";
|
||||
if (file_exists($f)) {
|
||||
echo "=== wtp-unified-dock.js (first 2000 chars) ===\n";
|
||||
echo substr(@file_get_contents($f), 0, 2500);
|
||||
echo "\n\n=== Size: " . filesize($f) . "B ===\n";
|
||||
// Find what paths show the dock
|
||||
$c = @file_get_contents($f);
|
||||
if (preg_match_all("/(pub|pathname|location|private|internal|allow|deny)[^\n]{0,200}/i", $c, $m)) {
|
||||
echo "\n=== path/pathname occurrences ===\n";
|
||||
foreach (array_slice($m[0], 0, 10) as $o) echo " $o\n";
|
||||
}
|
||||
}
|
||||
8
api/ambre-doctrine-112.php
Normal file
8
api/ambre-doctrine-112.php
Normal file
File diff suppressed because one or more lines are too long
8
api/ambre-doctrine-113.php
Normal file
8
api/ambre-doctrine-113.php
Normal file
File diff suppressed because one or more lines are too long
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
// V179 wevia-brand · user-visible strings use WEVIA Vision only
|
||||
/**
|
||||
* ambre-early-doc-gen.php · v4 · 5 capabilities réelles
|
||||
* 1. File gen pdf/docx/pptx via pandoc
|
||||
@@ -86,37 +87,56 @@ if (preg_match("/g[eéèê]n[eéèê]re?.*(sch[eéèê]ma|mermaid|diagramme|flow
|
||||
exit;
|
||||
}
|
||||
|
||||
// ========== HANDLER 4: Image SVG via LLM ==========
|
||||
if (preg_match("/g[eéèê]n[eéèê]re?\s+(?:une|un)?\s*image\s*(?:\b(?:decrivant|repr[eéèê]sentant|pour|sur|de)\b\s*)?:?\s*(.+)$/iu", $__ad_msg, $__im)) {
|
||||
// ========== HANDLER 4: Image via ambre-tool-image.php CASCADE (V177 image-gemini-cascade) ==========
|
||||
// V177: Replace LLM SVG by real image cascade (Gemini 3 Pro Image Preview primary, Qwen fallback, Pollinations last resort)
|
||||
if (preg_match("/g[e\xc3\xa9\xc3\xa8\xc3\xaa]n[e\xc3\xa9\xc3\xa8\xc3\xaa]re?\s+(?:une|un)?\s*image\s*(?:\b(?:decrivant|repr[e\xc3\xa9\xc3\xa8\xc3\xaa]sentant|pour|sur|de)\b\s*)?:?\s*(.+)$/iu", $__ad_msg, $__im)) {
|
||||
$__topic = trim($__im[1]);
|
||||
$__sys = "Tu es un generateur d\"images SVG. Reponds UNIQUEMENT avec du code SVG valide 400x300, pas de markdown, pas de backticks. Formes geometriques + couleurs. Commence par <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 400 300\">.";
|
||||
$__user = "SVG representant: $__topic";
|
||||
$__llm = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
|
||||
"http"=>["method"=>"POST","header"=>"Content-Type: application/json\r\n",
|
||||
"content"=>json_encode(["model"=>"fast","messages"=>[
|
||||
["role"=>"system","content"=>$__sys],["role"=>"user","content"=>$__user]
|
||||
],"max_tokens"=>700,"temperature"=>0.4]),"timeout"=>25]
|
||||
]));
|
||||
$__svg = @json_decode($__llm,true)["choices"][0]["message"]["content"] ?? "";
|
||||
$__svg = trim(preg_replace("/```(?:svg|xml)?\n?|```/","",$__svg));
|
||||
$__t0 = microtime(true);
|
||||
|
||||
if (strpos($__svg, "<svg") !== false) {
|
||||
// Save to /generated/
|
||||
$__ts = date("Ymd-His");
|
||||
$__rand = substr(md5(random_bytes(4)),0,6);
|
||||
$__safe = preg_replace("/[^a-zA-Z0-9\-_]/","-",substr($__topic,0,40));
|
||||
$__fname = "wevia-img-$__safe-$__ts-$__rand.svg";
|
||||
@file_put_contents("/var/www/html/generated/$__fname", $__svg);
|
||||
$__size = strlen($__svg);
|
||||
// Call ambre-tool-image.php directly (internal, loopback)
|
||||
$__img_ctx = stream_context_create([
|
||||
"http" => [
|
||||
"method" => "POST",
|
||||
"header" => "Content-Type: application/json\r\nHost: weval-consulting.com\r\n",
|
||||
"content" => json_encode(["prompt" => $__topic]),
|
||||
"timeout" => 75,
|
||||
"ignore_errors" => true,
|
||||
],
|
||||
]);
|
||||
$__img_resp = @file_get_contents("http://127.0.0.1/api/ambre-tool-image.php", false, $__img_ctx);
|
||||
$__img_d = @json_decode($__img_resp, true);
|
||||
|
||||
if ($__img_d && !empty($__img_d["success"]) && !empty($__img_d["url"])) {
|
||||
$__url = $__img_d["url"];
|
||||
$__provider = $__img_d["provider"] ?? "WEVIA Image Engine";
|
||||
$__quality = $__img_d["quality"] ?? "standard";
|
||||
$__size_kb = $__img_d["size_kb"] ?? 0;
|
||||
$__elapsed = round((microtime(true) - $__t0) * 1000);
|
||||
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
echo json_encode([
|
||||
"response"=>"🎨 **$__topic** (image SVG)\n\n🔗 Telecharger: https://weval-consulting.com/generated/$__fname\n📦 Taille: " . round($__size/1024,1) . "KB · engine: LLM+SVG\n\n" . chr(96) . chr(96) . chr(96) . "html\n$__svg\n" . chr(96) . chr(96) . chr(96),
|
||||
"executed"=>true,"provider"=>"ambre-doc-gen-v5","intent"=>"image_svg_real",
|
||||
"topic"=>$__topic, "url"=>"https://weval-consulting.com/generated/$__fname",
|
||||
], JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
|
||||
"response" => "\xf0\x9f\x8e\xa8 **$__topic**\n\n\xf0\x9f\x94\x97 T\xc3\xa9l\xc3\xa9charger: $__url\n\xf0\x9f\x93\xa6 Taille: {$__size_kb}KB \xc2\xb7 \xe2\x9a\x99\xef\xb8\x8f {$__elapsed}ms \xc2\xb7 engine: $__provider",
|
||||
"executed" => true,
|
||||
"provider" => "ambre-doc-gen-v5",
|
||||
"intent" => "image_real_cascade",
|
||||
"topic" => $__topic,
|
||||
"url" => $__url,
|
||||
"quality" => $__quality,
|
||||
"image_provider" => $__provider,
|
||||
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
exit;
|
||||
}
|
||||
// If cascade failed, fall through (old LLM SVG code removed to force real images)
|
||||
// Return an informative error to widget rather than fake SVG
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
echo json_encode([
|
||||
"response" => "\xe2\x9a\xa0\xef\xb8\x8f G\xc3\xa9n\xc3\xa9ration d\"image temporairement indisponible pour: $__topic. WEVIA Vision temporairement indisponible. Les providers internes ont \xc3\xa9chou\xc3\xa9. R\xc3\xa9essayez dans quelques instants.",
|
||||
"executed" => true,
|
||||
"provider" => "ambre-doc-gen-v5",
|
||||
"intent" => "image_cascade_failed",
|
||||
"topic" => $__topic,
|
||||
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ========== HANDLER 5: Code generation with file ==========
|
||||
|
||||
21
api/ambre-export-v46.php
Normal file
21
api/ambre-export-v46.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$src = "/var/www/html/api/ambre-pw-tests/output";
|
||||
$dst = "/var/www/html/generated";
|
||||
$out = ["copied"=>[]];
|
||||
foreach (glob("$src/v46-*.png") as $s) {
|
||||
$bn = "wevia-v46-multiagent-" . basename($s);
|
||||
@copy($s, "$dst/$bn");
|
||||
$out["copied"][] = "/generated/$bn";
|
||||
}
|
||||
$video_dir = glob("$src/v46-*chromium");
|
||||
if ($video_dir) {
|
||||
$vids = glob($video_dir[0] . "/video.webm");
|
||||
if ($vids) {
|
||||
$dv = "$dst/wevia-v46-multiagent-proof-" . date("Ymd-His") . ".webm";
|
||||
@copy($vids[0], $dv);
|
||||
@chmod($dv, 0644);
|
||||
$out["video"] = ["url"=>"/generated/".basename($dv), "size_mb"=>round(filesize($dv)/1024/1024, 2)];
|
||||
}
|
||||
}
|
||||
echo json_encode($out, JSON_UNESCAPED_SLASHES);
|
||||
21
api/ambre-export-v47.php
Normal file
21
api/ambre-export-v47.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$src = "/var/www/html/api/ambre-pw-tests/output";
|
||||
$dst = "/var/www/html/generated";
|
||||
$out = ["copied"=>[]];
|
||||
foreach (glob("$src/v47-*.png") as $s) {
|
||||
$bn = "wevia-v47-widget-" . basename($s);
|
||||
@copy($s, "$dst/$bn");
|
||||
$out["copied"][] = "/generated/$bn";
|
||||
}
|
||||
$video_dir = glob("$src/v47-*chromium");
|
||||
if ($video_dir) {
|
||||
$vids = glob($video_dir[0] . "/video.webm");
|
||||
if ($vids) {
|
||||
$dv = "$dst/wevia-v47-widget-proof-" . date("Ymd-His") . ".webm";
|
||||
@copy($vids[0], $dv);
|
||||
@chmod($dv, 0644);
|
||||
$out["video"] = ["url"=>"/generated/".basename($dv), "size_mb"=>round(filesize($dv)/1024/1024, 2)];
|
||||
}
|
||||
}
|
||||
echo json_encode($out, JSON_UNESCAPED_SLASHES);
|
||||
21
api/ambre-export-v48.php
Normal file
21
api/ambre-export-v48.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$src = "/var/www/html/api/ambre-pw-tests/output";
|
||||
$dst = "/var/www/html/generated";
|
||||
$out = ["copied"=>[]];
|
||||
foreach (glob("$src/v48-*.png") as $s) {
|
||||
$bn = "wevia-v48-showcase-" . basename($s);
|
||||
@copy($s, "$dst/$bn");
|
||||
$out["copied"][] = "/generated/$bn";
|
||||
}
|
||||
$video_dir = glob("$src/v48-*chromium");
|
||||
if ($video_dir) {
|
||||
$vids = glob($video_dir[0] . "/video.webm");
|
||||
if ($vids) {
|
||||
$dv = "$dst/wevia-v48-showcase-" . date("Ymd-His") . ".webm";
|
||||
@copy($vids[0], $dv);
|
||||
@chmod($dv, 0644);
|
||||
$out["video"] = ["url"=>"/generated/".basename($dv), "size_mb"=>round(filesize($dv)/1024/1024, 2)];
|
||||
}
|
||||
}
|
||||
echo json_encode($out, JSON_UNESCAPED_SLASHES);
|
||||
11
api/ambre-export-v50.php
Normal file
11
api/ambre-export-v50.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$src = "/var/www/html/api/ambre-pw-tests/output";
|
||||
$dst = "/var/www/html/generated";
|
||||
$out = ["copied"=>[]];
|
||||
foreach (glob("$src/v50-*.png") as $s) {
|
||||
$bn = "wevia-v50-shield-" . basename($s);
|
||||
@copy($s, "$dst/$bn");
|
||||
$out["copied"][] = "/generated/$bn";
|
||||
}
|
||||
echo json_encode($out, JSON_UNESCAPED_SLASHES);
|
||||
27
api/ambre-ext-probe.php
Normal file
27
api/ambre-ext-probe.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
// Ollama models available
|
||||
$ol = @file_get_contents("http://127.0.0.1:11434/api/tags", false, stream_context_create(["http"=>["timeout"=>3]]));
|
||||
$od = @json_decode($ol, true);
|
||||
$out["ollama_models"] = is_array($od) ? array_map(function($m){return $m["name"];}, $od["models"] ?? []) : [];
|
||||
|
||||
// Paperclip health/API
|
||||
$pc = @file_get_contents("http://127.0.0.1:3201/", false, stream_context_create(["http"=>["timeout"=>3,"ignore_errors"=>true]]));
|
||||
$out["paperclip_first"] = substr($pc ?? "", 0, 200);
|
||||
|
||||
// DeerFlow api probe
|
||||
$df = @file_get_contents("http://127.0.0.1:3002/api/health", false, stream_context_create(["http"=>["timeout"=>3,"ignore_errors"=>true]]));
|
||||
$out["deerflow_health"] = substr($df ?? "", 0, 150);
|
||||
|
||||
// Cascade providers health (all 13)
|
||||
$ch = @file_get_contents("http://127.0.0.1:4000/health", false, stream_context_create(["http"=>["timeout"=>3]]));
|
||||
$cd = @json_decode($ch, true);
|
||||
$out["cascade_providers"] = is_array($cd) ? ($cd["providers"] ?? $cd) : $ch;
|
||||
|
||||
// L99 (S95 arsenal) probe
|
||||
$l99 = @file_get_contents("http://127.0.0.1:5890/api/l99-health.php", false, stream_context_create(["http"=>["timeout"=>3,"ignore_errors"=>true]]));
|
||||
$out["l99_health"] = substr($l99 ?? "", 0, 150);
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
29
api/ambre-find-mermaid.php
Normal file
29
api/ambre-find-mermaid.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$c = @file_get_contents("/var/www/html/wevia.html");
|
||||
|
||||
// Look for the Result/Resultat etape 5 rendering in V5-CLAUDE-PATTERN (now V5-WEVIA-PATTERN)
|
||||
// Find where the result appears
|
||||
$pos = strpos($c, "Resultat");
|
||||
while ($pos !== false) {
|
||||
$ctx = substr($c, max(0, $pos - 100), 600);
|
||||
if (strpos($ctx, "schema") !== false || strpos($ctx, "Mermaid") !== false || strpos($ctx, "mermaid") !== false) {
|
||||
echo "=== Context at $pos ===\n";
|
||||
echo $ctx;
|
||||
echo "\n\n---\n";
|
||||
}
|
||||
$pos = strpos($c, "Resultat", $pos + 1);
|
||||
}
|
||||
|
||||
// Find how the final SVG is supposed to render
|
||||
echo "\n\n=== Search mermaid.render in wevia.html ===\n";
|
||||
if (preg_match_all('/mermaid\.render\([^)]+\)/', $c, $m)) {
|
||||
foreach (array_slice($m[0], 0, 5) as $match) echo " $match\n";
|
||||
}
|
||||
|
||||
// Find the Schema rendering fct
|
||||
echo "\n=== Search Schema Mermaid rendering code ===\n";
|
||||
$pos = strpos($c, "Schema Mermaid:");
|
||||
if ($pos !== false) {
|
||||
echo substr($c, max(0, $pos - 200), 800);
|
||||
}
|
||||
21
api/ambre-find-panel.php
Normal file
21
api/ambre-find-panel.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$c = @file_get_contents("/var/www/html/wevia-widget.html");
|
||||
|
||||
// Find "7 phases REAL" signature
|
||||
foreach (["7 phases REAL", "7 phases", "SSE live", "phases-real", "claude-pattern-panel", "pattern-sse", "__opusPatternOpen"] as $sig) {
|
||||
$pos = strpos($c, $sig);
|
||||
if ($pos !== false) {
|
||||
echo "=== Found '$sig' at $pos ===\n";
|
||||
echo substr($c, max(0, $pos - 300), 600);
|
||||
echo "\n\n---\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Find backend=wevia-widget context
|
||||
$pos2 = strpos($c, "backend");
|
||||
if ($pos2 !== false) {
|
||||
echo "\n=== backend ctx ===\n";
|
||||
echo substr($c, max(0, $pos2 - 200), 500);
|
||||
}
|
||||
28
api/ambre-find-result.php
Normal file
28
api/ambre-find-result.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$c = @file_get_contents("/var/www/html/wevia.html");
|
||||
|
||||
// Find how the result payload is handled in SSE (type === "result")
|
||||
$pos = strpos($c, "type === 'result'");
|
||||
while ($pos !== false && $pos < 250000) {
|
||||
echo "=== Position $pos ===\n";
|
||||
echo substr($c, $pos, 800);
|
||||
echo "\n\n---\n";
|
||||
$pos = strpos($c, "type === 'result'", $pos + 10);
|
||||
if ($pos > strpos($c, "type === 'result'") + 100) break;
|
||||
}
|
||||
// Also check the 'schema' output handling
|
||||
$pos2 = strpos($c, "Schema Mermaid");
|
||||
echo "\n\n=== Schema Mermaid: $pos2 ===\n";
|
||||
if ($pos2 !== false) echo substr($c, max(0, $pos2 - 500), 1200);
|
||||
|
||||
// Check if the result step handles mermaid_code field
|
||||
echo "\n\n=== Look for mermaid_code field handler ===\n";
|
||||
if (preg_match_all('/mermaid_code[^,;]{0,300}/', $c, $m)) {
|
||||
foreach (array_slice($m[0], 0, 5) as $match) echo " " . substr($match, 0, 200) . "\n";
|
||||
}
|
||||
|
||||
// Also Resultat phase 5/5 rendering
|
||||
$pos3 = strpos($c, "Resultat");
|
||||
echo "\n\n=== Resultat: $pos3 ===\n";
|
||||
if ($pos3 !== false) echo substr($c, max(0, $pos3 - 100), 900);
|
||||
28
api/ambre-find-result2.php
Normal file
28
api/ambre-find-result2.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$c = @file_get_contents("/var/www/html/wevia.html");
|
||||
|
||||
// Find "Resultat" encoded
|
||||
echo "=== Stage 5/5 result patterns ===\n";
|
||||
foreach (["'result'", "\"result\"", "R\u00e9sultat", "Schema Mermaid", "phase.*result", "etape.*5"] as $pat) {
|
||||
if (preg_match_all("/$pat/", $c, $m, PREG_OFFSET_CAPTURE)) {
|
||||
echo " '$pat' matches at: ";
|
||||
foreach (array_slice($m[0], 0, 3) as $hit) echo $hit[1] . " ";
|
||||
echo "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Find the SSE result handler code
|
||||
$pos = strpos($c, "type === 'result'");
|
||||
if ($pos === false) $pos = strpos($c, "type=='result'");
|
||||
if ($pos === false) $pos = strpos($c, "=== \"result\"");
|
||||
echo "\n=== result type at: $pos ===\n";
|
||||
if ($pos !== false) {
|
||||
echo substr($c, $pos, 1200);
|
||||
}
|
||||
|
||||
// Also search the output_data or schema_url handling
|
||||
echo "\n\n=== schema_url / output_data ===\n";
|
||||
if (preg_match_all('/schema_url|output_data|schema_content/', $c, $m)) {
|
||||
foreach ($m[0] as $match) echo " $match\n";
|
||||
}
|
||||
144
api/ambre-internal-chat-api.php
Normal file
144
api/ambre-internal-chat-api.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-internal-chat-api.php · wave-259 · Unified chat API for INTERNAL chatbots
|
||||
*
|
||||
* Features:
|
||||
* - Persistent memory (AmbreInternalMemory · /opt/wevads/internal-memory/)
|
||||
* - Cross-chat learning (shared KB: all chats contribute to common learning pool)
|
||||
* - Zero CF cache (Cache-Control headers + CF-Cache-Status: BYPASS)
|
||||
* - LLM semaphore-protected
|
||||
* - Auto-identity extraction
|
||||
* - Multi-agent dispatcher if complex query
|
||||
*
|
||||
* POST { chat_id, message, enable_multiagent: true/false }
|
||||
*/
|
||||
|
||||
// FORCE NO CF CACHE
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
|
||||
header("CDN-Cache-Control: no-store");
|
||||
header("Cloudflare-CDN-Cache-Control: no-store");
|
||||
header("Pragma: no-cache");
|
||||
header("Expires: 0");
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
|
||||
require_once __DIR__ . "/ambre-internal-memory.php";
|
||||
@require_once __DIR__ . "/ambre-llm-semaphore.php";
|
||||
|
||||
$t0 = microtime(true);
|
||||
$raw = file_get_contents("php://input");
|
||||
$in = json_decode($raw, true) ?: $_POST;
|
||||
|
||||
$chat_id = trim($in["chat_id"] ?? "");
|
||||
$msg = trim($in["message"] ?? "");
|
||||
$enable_ma = !empty($in["enable_multiagent"]);
|
||||
|
||||
if (!$msg) { echo json_encode(["error"=>"message required"]); exit; }
|
||||
if (!$chat_id) $chat_id = "internal-" . substr(md5(($_SERVER["REMOTE_ADDR"] ?? "x") . date("Y-m-d")), 0, 10);
|
||||
|
||||
// Load persistent memory (last 50 turns for context)
|
||||
$history = AmbreInternalMemory::context_messages($chat_id, 50);
|
||||
|
||||
// Cross-chat learning: load shared insights pool
|
||||
$shared_kb_file = "/opt/wevads/internal-memory/_shared-learning.json";
|
||||
$shared_kb = @json_decode(@file_get_contents($shared_kb_file), true) ?: [];
|
||||
|
||||
// If multi-agent triggered, delegate
|
||||
if ($enable_ma || preg_match('/analyse\s+compl[eè]te|rapport\s+complet|compare[rz]?\s+.{3,}\s+(?:avec|vs|contre|et)|multi[- ]?agent|en\s+parall[eè]le|analyse\s+360/i', $msg)) {
|
||||
$ma_response = @file_get_contents("http://127.0.0.1/api/ambre-multiagent-parallel.php", false, stream_context_create([
|
||||
"http" => [
|
||||
"method" => "POST",
|
||||
"header" => "Content-Type: application/json\r\n",
|
||||
"content" => json_encode(["goal" => $msg, "max_agents" => 6]),
|
||||
"timeout" => 60,
|
||||
],
|
||||
]));
|
||||
$ma_data = @json_decode($ma_response, true);
|
||||
if ($ma_data && !empty($ma_data["ok"])) {
|
||||
// Append to memory
|
||||
AmbreInternalMemory::append($chat_id, "user", $msg);
|
||||
AmbreInternalMemory::append($chat_id, "assistant", $ma_data["reconciled"], ["mode"=>"multiagent", "agents"=>$ma_data["agents_count"]]);
|
||||
|
||||
// Extract learning for cross-chat KB
|
||||
if (isset($ma_data["plan"]["objective"])) {
|
||||
$shared_kb[] = [
|
||||
"ts" => time(),
|
||||
"chat_id" => $chat_id,
|
||||
"topic" => $ma_data["plan"]["objective"],
|
||||
"synthesis_preview" => substr($ma_data["reconciled"], 0, 300),
|
||||
];
|
||||
if (count($shared_kb) > 500) $shared_kb = array_slice($shared_kb, -500);
|
||||
@file_put_contents($shared_kb_file, json_encode($shared_kb, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
"ok" => true,
|
||||
"mode" => "multiagent",
|
||||
"response" => $ma_data["reconciled"],
|
||||
"plan" => $ma_data["plan"],
|
||||
"agents" => $ma_data["results"],
|
||||
"total_ms" => round((microtime(true)-$t0)*1000),
|
||||
"memory_turns" => count(AmbreInternalMemory::load($chat_id)),
|
||||
"shared_kb_size" => count($shared_kb),
|
||||
"cache_bypass" => true,
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Standard path: LLM with memory + cross-chat hints
|
||||
$sys_parts = [
|
||||
"Tu es un agent WEVAL Consulting, spécialisé et informé.",
|
||||
"Tu mémorises toute la conversation (mémoire persistante illimitée).",
|
||||
"Tu adaptes ton ton au contexte.",
|
||||
"Si la question est complexe, propose un multi-agent pour détailler.",
|
||||
"Réponds en français clair et actionnable.",
|
||||
];
|
||||
|
||||
// Inject cross-chat hints (last 3 topics discussed on this server)
|
||||
if (!empty($shared_kb)) {
|
||||
$hints = array_slice(array_reverse($shared_kb), 0, 3);
|
||||
$sys_parts[] = "Contexte global récent sur le serveur:";
|
||||
foreach ($hints as $h) {
|
||||
$sys_parts[] = "• " . substr($h["topic"] ?? "", 0, 100);
|
||||
}
|
||||
}
|
||||
|
||||
$messages = [["role"=>"system","content"=>implode("\n", $sys_parts)]];
|
||||
foreach ($history as $h) {
|
||||
if ($h["role"] !== "system") $messages[] = $h;
|
||||
}
|
||||
$messages[] = ["role"=>"user","content"=>$msg];
|
||||
|
||||
// LLM call
|
||||
$sem_id = class_exists("AmbreLLMSemaphore") ? @AmbreLLMSemaphore::acquire() : null;
|
||||
$llm_t0 = microtime(true);
|
||||
$llm_raw = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
|
||||
"http" => [
|
||||
"method" => "POST",
|
||||
"header" => "Content-Type: application/json\r\n",
|
||||
"content" => json_encode(["model"=>"fast", "messages"=>$messages, "max_tokens"=>800]),
|
||||
"timeout" => 30,
|
||||
],
|
||||
]));
|
||||
if ($sem_id && class_exists("AmbreLLMSemaphore")) @AmbreLLMSemaphore::release($sem_id);
|
||||
|
||||
$llm_data = @json_decode($llm_raw, true);
|
||||
$reply = $llm_data["choices"][0]["message"]["content"] ?? "Erreur LLM";
|
||||
$llm_ms = round((microtime(true)-$llm_t0)*1000);
|
||||
|
||||
// Persist
|
||||
AmbreInternalMemory::append($chat_id, "user", $msg);
|
||||
AmbreInternalMemory::append($chat_id, "assistant", $reply, ["llm_ms"=>$llm_ms]);
|
||||
|
||||
echo json_encode([
|
||||
"ok" => true,
|
||||
"mode" => "standard",
|
||||
"response" => $reply,
|
||||
"total_ms" => round((microtime(true)-$t0)*1000),
|
||||
"llm_ms" => $llm_ms,
|
||||
"memory_turns" => count(AmbreInternalMemory::load($chat_id)),
|
||||
"shared_kb_size" => count($shared_kb),
|
||||
"cache_bypass" => true,
|
||||
"chat_id" => $chat_id,
|
||||
]);
|
||||
123
api/ambre-internal-memory.php
Normal file
123
api/ambre-internal-memory.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-internal-memory.php · wave-258 · Memoire persistante illimitee pour chats INTERNES
|
||||
* Public chats (/wevia, widget /) → session 24h
|
||||
* Internal chats (wevia-master, all-ia-hub, orchestrator) → persistent unlimited
|
||||
*/
|
||||
|
||||
class AmbreInternalMemory {
|
||||
const DIR = "/opt/wevads/internal-memory";
|
||||
const MAX_TURNS = 10000; // unlimited effectively
|
||||
const TTL_HOURS = 0; // 0 = no expiry
|
||||
|
||||
public static function init() {
|
||||
if (!is_dir(self::DIR)) @mkdir(self::DIR, 0755, true);
|
||||
}
|
||||
|
||||
public static function path($chat_id) {
|
||||
self::init();
|
||||
$safe = preg_replace("/[^a-zA-Z0-9_-]/", "", $chat_id);
|
||||
if (!$safe) $safe = "default";
|
||||
return self::DIR . "/" . $safe . ".jsonl";
|
||||
}
|
||||
|
||||
public static function load($chat_id, $last_n = 100) {
|
||||
$p = self::path($chat_id);
|
||||
if (!file_exists($p)) return [];
|
||||
$lines = @file($p, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
if (!$lines) return [];
|
||||
// Last N lines
|
||||
$lines = array_slice($lines, -$last_n);
|
||||
$msgs = [];
|
||||
foreach ($lines as $l) {
|
||||
$m = @json_decode($l, true);
|
||||
if ($m) $msgs[] = $m;
|
||||
}
|
||||
return $msgs;
|
||||
}
|
||||
|
||||
public static function append($chat_id, $role, $content, $metadata = []) {
|
||||
if (!$chat_id || !$role || !$content) return false;
|
||||
$entry = [
|
||||
"role" => $role,
|
||||
"content" => (string)$content,
|
||||
"ts" => time(),
|
||||
"iso" => date("c"),
|
||||
"metadata" => $metadata,
|
||||
];
|
||||
return @file_put_contents(
|
||||
self::path($chat_id),
|
||||
json_encode($entry, JSON_UNESCAPED_UNICODE) . "\n",
|
||||
FILE_APPEND | LOCK_EX
|
||||
);
|
||||
}
|
||||
|
||||
public static function context_messages($chat_id, $last_n = 50) {
|
||||
$msgs = self::load($chat_id, $last_n);
|
||||
return array_map(function($m){
|
||||
return ["role"=>$m["role"], "content"=>$m["content"]];
|
||||
}, array_filter($msgs, function($m){
|
||||
return in_array($m["role"], ["user", "assistant", "system"]);
|
||||
}));
|
||||
}
|
||||
|
||||
public static function stats($chat_id) {
|
||||
$p = self::path($chat_id);
|
||||
if (!file_exists($p)) return ["exists"=>false, "turns"=>0, "size"=>0];
|
||||
$lines = @file($p, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
return [
|
||||
"exists" => true,
|
||||
"turns" => count($lines ?: []),
|
||||
"size_bytes" => filesize($p),
|
||||
"path" => $p,
|
||||
"first" => ($lines && $lines[0]) ? @json_decode($lines[0], true)["iso"] ?? "?" : "?",
|
||||
"last" => ($lines && end($lines)) ? @json_decode(end($lines), true)["iso"] ?? "?" : "?",
|
||||
];
|
||||
}
|
||||
|
||||
public static function list_chats() {
|
||||
self::init();
|
||||
$out = [];
|
||||
foreach (glob(self::DIR . "/*.jsonl") as $f) {
|
||||
$bn = basename($f, ".jsonl");
|
||||
$lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
$out[] = [
|
||||
"chat_id" => $bn,
|
||||
"turns" => count($lines ?: []),
|
||||
"size_kb" => round(filesize($f)/1024, 1),
|
||||
"mtime" => date("c", filemtime($f)),
|
||||
];
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
// If called directly via HTTP, act as API
|
||||
if (php_sapi_name() !== "cli" && basename($_SERVER["SCRIPT_FILENAME"] ?? "") === "ambre-internal-memory.php") {
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
$raw = file_get_contents("php://input");
|
||||
$in = json_decode($raw, true) ?: $_GET;
|
||||
$action = $in["action"] ?? "stats";
|
||||
$chat_id = $in["chat_id"] ?? "";
|
||||
|
||||
switch ($action) {
|
||||
case "append":
|
||||
$result = AmbreInternalMemory::append($chat_id, $in["role"] ?? "user", $in["content"] ?? "", $in["metadata"] ?? []);
|
||||
echo json_encode(["ok"=>(bool)$result, "written"=>$result]);
|
||||
break;
|
||||
case "load":
|
||||
echo json_encode(["ok"=>true, "messages"=>AmbreInternalMemory::load($chat_id, intval($in["n"] ?? 100))]);
|
||||
break;
|
||||
case "context":
|
||||
echo json_encode(["ok"=>true, "messages"=>AmbreInternalMemory::context_messages($chat_id, intval($in["n"] ?? 50))]);
|
||||
break;
|
||||
case "stats":
|
||||
echo json_encode(["ok"=>true, "stats"=>AmbreInternalMemory::stats($chat_id)]);
|
||||
break;
|
||||
case "list":
|
||||
echo json_encode(["ok"=>true, "chats"=>AmbreInternalMemory::list_chats()]);
|
||||
break;
|
||||
default:
|
||||
echo json_encode(["error"=>"unknown action. Use: append|load|context|stats|list"]);
|
||||
}
|
||||
}
|
||||
29
api/ambre-leak-find.php
Normal file
29
api/ambre-leak-find.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$w = @file_get_contents("/var/www/html/wevia.html");
|
||||
|
||||
// Find the Claude Pattern panel HTML source
|
||||
$pos = strpos($w, "Claude Pattern");
|
||||
if ($pos !== false) {
|
||||
echo "=== wevia.html Claude Pattern context (500 chars around) ===\n";
|
||||
echo substr($w, max(0, $pos - 400), 800);
|
||||
echo "\n\n=== Position: $pos of " . strlen($w) . " ===\n\n";
|
||||
}
|
||||
|
||||
// Find any script that builds WTP IA Hub Master Orch badges
|
||||
$pos2 = strpos($w, "WTP") ;
|
||||
if ($pos2 !== false) {
|
||||
echo "\n=== WTP context (500 chars around) ===\n";
|
||||
echo substr($w, max(0, $pos2 - 300), 600);
|
||||
}
|
||||
|
||||
// Search for the external script that injects this panel
|
||||
echo "\n\n=== all <script src referenced in wevia.html ===\n";
|
||||
preg_match_all('/<script[^>]*src=["\']([^"\']+)["\']/', $w, $m);
|
||||
foreach (array_unique($m[1] ?? []) as $s) echo " $s\n";
|
||||
|
||||
// Root index
|
||||
echo "\n=== index.html root - check for same panel sources ===\n";
|
||||
$root = @file_get_contents("/var/www/html/index.html");
|
||||
preg_match_all('/<script[^>]*src=["\']([^"\']+)["\']/', $root, $m2);
|
||||
foreach (array_unique($m2[1] ?? []) as $s) echo " $s\n";
|
||||
46
api/ambre-leak-scan.php
Normal file
46
api/ambre-leak-scan.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
// Check / root index widget + /wevia public
|
||||
$root = @file_get_contents("/var/www/html/index.html");
|
||||
$out["root"] = [
|
||||
"size" => strlen($root ?? ""),
|
||||
"has_claude_pattern" => preg_match_all("/Claude\s*Pattern/i", $root ?? ""),
|
||||
"has_wtp_admin_ia_hub_master_orch" => preg_match_all("/\b(WTP|IA Hub|Master|Orch|WevCode|Arena|Droid|Admin|WEVIA Engine)\b/", $root ?? ""),
|
||||
"has_chattbot_modules" => preg_match_all("/nx-badge|claude-pattern|chat-modules/i", $root ?? ""),
|
||||
];
|
||||
|
||||
// Check wevia.html (public /wevia)
|
||||
$wevia = @file_get_contents("/var/www/html/wevia.html");
|
||||
$out["wevia_public"] = [
|
||||
"size" => strlen($wevia ?? ""),
|
||||
"has_claude_pattern_text" => preg_match_all("/Claude\s*Pattern/i", $wevia ?? ""),
|
||||
"has_internal_shortcuts" => preg_match_all("/\b(WTP|IA Hub|Master|Orch|WevCode|Arena|Droid|Admin|WEVIA Engine)\b/", $wevia ?? ""),
|
||||
"has_dashboards_shortcut" => strpos($wevia ?? "", "Dashboards") !== false,
|
||||
];
|
||||
|
||||
// Find the HTML source rendering Claude Pattern + WTP/Hub/Master badges
|
||||
// Most likely a panel in bottom-right of pages
|
||||
$out["sources_with_claude_pattern"] = [];
|
||||
foreach (glob("/var/www/html/*.html") as $f) {
|
||||
$c = @file_get_contents($f);
|
||||
if (preg_match("/Claude\s*Pattern/i", $c) || (strpos($c, "WTP") !== false && strpos($c, "Droid") !== false && strpos($c, "Orch") !== false)) {
|
||||
$out["sources_with_claude_pattern"][] = [
|
||||
"file" => basename($f),
|
||||
"size" => filesize($f),
|
||||
"has_claude_p" => (bool)preg_match("/Claude\s*Pattern/i", $c),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Also check JS files
|
||||
$out["js_with_claude_pattern"] = [];
|
||||
foreach (array_merge(glob("/var/www/html/js/*.js") ?: [], glob("/var/www/html/api/*.js") ?: []) as $f) {
|
||||
$c = @file_get_contents($f);
|
||||
if (preg_match("/Claude\s*Pattern/i", $c)) {
|
||||
$out["js_with_claude_pattern"][] = ["file"=>str_replace("/var/www/html", "", $f), "size"=>filesize($f)];
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
5
api/ambre-mem-read.php
Normal file
5
api/ambre-mem-read.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$f = "/var/www/html/api/ambre-session-memory.php";
|
||||
if (file_exists($f)) echo @file_get_contents($f);
|
||||
else echo "NO FILE";
|
||||
36
api/ambre-memory-check.php
Normal file
36
api/ambre-memory-check.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
// Widget / root index
|
||||
$root = @file_get_contents("/var/www/html/index.html");
|
||||
$out["root_size"] = strlen($root ?? "");
|
||||
$out["widget_has_sessionstorage"] = strpos($root ?? "", "sessionStorage") !== false;
|
||||
$out["widget_has_localstorage"] = strpos($root ?? "", "localStorage") !== false;
|
||||
$out["widget_has_wevia"] = preg_match_all("/wevia/i", $root ?? "");
|
||||
|
||||
// Widget bubbler for persistent backend
|
||||
$wevia_public = @file_get_contents("/var/www/html/wevia.html");
|
||||
$out["wevia_public_size"] = strlen($wevia_public ?? "");
|
||||
$out["wevia_has_sessionstorage"] = strpos($wevia_public ?? "", "sessionStorage") !== false;
|
||||
$out["wevia_has_session_id"] = strpos($wevia_public ?? "", "_ambre_session_id") !== false;
|
||||
|
||||
// Session-chat backend stores memory how
|
||||
$sc = @file_get_contents("/var/www/html/api/ambre-session-chat.php");
|
||||
$out["session_chat_size"] = strlen($sc ?? "");
|
||||
$out["session_chat_storage"] = [];
|
||||
if ($sc) {
|
||||
if (strpos($sc, "file_put_contents") !== false) $out["session_chat_storage"][] = "file";
|
||||
if (strpos($sc, "sqlite") !== false) $out["session_chat_storage"][] = "sqlite";
|
||||
if (strpos($sc, "redis") !== false) $out["session_chat_storage"][] = "redis";
|
||||
// Find TTL
|
||||
if (preg_match("/(\d{4,}).*TTL|TTL.*?(\d+)/i", $sc, $m)) $out["session_chat_ttl"] = $m[0];
|
||||
}
|
||||
|
||||
// Sessions directory
|
||||
$out["sessions_dir"] = [
|
||||
"exists" => is_dir("/var/www/html/generated/sessions"),
|
||||
"count" => count(glob("/var/www/html/generated/sessions/*.json") ?: []),
|
||||
];
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
72
api/ambre-mermaid-wire.php
Normal file
72
api/ambre-mermaid-wire.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/wevia.html";
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
|
||||
// Find the done handler and augment it with mermaid rendering
|
||||
// The anchor: 'else if (type === \'done\') {' to its closing brace
|
||||
$anchor = "else if (type === 'done') {
|
||||
finalFileUrl = data.file_url;";
|
||||
|
||||
if (strpos($c, $anchor) === false) {
|
||||
echo json_encode(["error"=>"done handler anchor not found"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Replace with enhanced version that renders mermaid when detected
|
||||
$new = "else if (type === 'done') {
|
||||
finalFileUrl = data.file_url;
|
||||
// === AMBRE-V5-MERMAID-RENDER wave-263 ===
|
||||
// If fullResponse contains mermaid code → render SVG inline
|
||||
try {
|
||||
var _mcode = null;
|
||||
if (data.mermaid_code) _mcode = data.mermaid_code;
|
||||
else if (fullResponse) {
|
||||
// Detect mermaid patterns at start of response
|
||||
var _fr = fullResponse.trim();
|
||||
if (/^(sequenceDiagram|flowchart|graph\s+[A-Z]{1,2}|classDiagram|stateDiagram|erDiagram|gantt|pie|journey|gitGraph|mindmap|timeline)\b/.test(_fr)) {
|
||||
_mcode = _fr;
|
||||
} else {
|
||||
// Search inside for ``` mermaid block
|
||||
var _m = fullResponse.match(/```mermaid\\s*([\\s\\S]+?)```/);
|
||||
if (_m) _mcode = _m[1].trim();
|
||||
else {
|
||||
// or raw mermaid after 'Schema Mermaid:' label
|
||||
var _m2 = fullResponse.match(/(?:Schema Mermaid|Diagramme)[^\\n]*\\n([\\s\\S]+)$/i);
|
||||
if (_m2 && /^(sequenceDiagram|flowchart|graph|classDiagram|stateDiagram)/.test(_m2[1].trim())) _mcode = _m2[1].trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_mcode && window.mermaid && currentPhaseEl) {
|
||||
// Sanitize accents for mermaid parser
|
||||
var _clean = _mcode.normalize ? _mcode.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '') : _mcode;
|
||||
var _svgId = 'wv-mermaid-' + Date.now() + '-' + Math.floor(Math.random()*999);
|
||||
var _mContainer = document.createElement('div');
|
||||
_mContainer.id = _svgId + '-wrap';
|
||||
_mContainer.style.cssText = 'margin-top:12px;padding:16px;background:#fafafa;border:1px solid #e5e7eb;border-radius:8px;overflow-x:auto';
|
||||
currentPhaseEl.appendChild(_mContainer);
|
||||
try {
|
||||
window.mermaid.render(_svgId, _clean).then(function(r){
|
||||
_mContainer.innerHTML = r.svg;
|
||||
}).catch(function(err){
|
||||
_mContainer.innerHTML = '<pre style=\"color:#b91c1c;font-size:11px\">Mermaid render error: ' + (err.message||err) + '\\n\\n' + _clean.replace(/</g,'<') + '</pre>';
|
||||
});
|
||||
} catch(e) {
|
||||
_mContainer.innerHTML = '<pre style=\"font-size:11px\">' + _clean.replace(/</g,'<') + '</pre>';
|
||||
}
|
||||
}
|
||||
} catch(eMermaid) { console.warn('[V5-MERMAID-RENDER]', eMermaid); }
|
||||
// === END AMBRE-V5-MERMAID-RENDER ===";
|
||||
|
||||
$c = str_replace($anchor, $new, $c);
|
||||
|
||||
$backup = "/opt/wevads/vault/wevia.html.GOLD-" . date("Ymd-His") . "-wave263-mermaid";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $c);
|
||||
|
||||
echo json_encode([
|
||||
"delta" => strlen($c) - $orig,
|
||||
"wrote" => $wrote,
|
||||
"backup" => basename($backup),
|
||||
]);
|
||||
213
api/ambre-multiagent-v2-external.php
Normal file
213
api/ambre-multiagent-v2-external.php
Normal file
@@ -0,0 +1,213 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-multiagent-v2-external.php · wave-260
|
||||
* MAX parallelism mobilisant IA EXTERNES + internes
|
||||
* Agents peuvent être : cascade fast | cascade think | ollama local | tool natif
|
||||
*/
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
header("Cache-Control: no-store, no-cache");
|
||||
header("CDN-Cache-Control: no-store");
|
||||
set_time_limit(120);
|
||||
|
||||
$raw = file_get_contents("php://input");
|
||||
$in = json_decode($raw, true) ?: $_POST;
|
||||
$goal = trim($in["goal"] ?? $in["message"] ?? "");
|
||||
$max_agents = min(12, max(2, intval($in["max_agents"] ?? 6)));
|
||||
|
||||
if (!$goal) { echo json_encode(["error"=>"goal required"]); exit; }
|
||||
|
||||
$t0 = microtime(true);
|
||||
|
||||
// PLAN with richer agent diversity
|
||||
$plan_sys = "Tu es un planificateur multi-agent WEVAL. Pour l'objectif donné, génère UN JSON STRICT :\n" .
|
||||
"{\n" .
|
||||
' "objective": "<reformulation>",' . "\n" .
|
||||
' "agents": [' . "\n" .
|
||||
' {"role":"<nom>", "task":"<tâche autonome>", "tool":"<type>", "model_hint":"<fast|think|ollama|tool_spec>"},' . "\n" .
|
||||
" ...\n" .
|
||||
" ]\n" .
|
||||
"}\n" .
|
||||
"Tools disponibles:\n" .
|
||||
"- llm_fast (Cerebras/Groq rapide)\n" .
|
||||
"- llm_think (Cerebras think raisonnement profond)\n" .
|
||||
"- llm_ollama (local qwen3/llama3.2 souverain)\n" .
|
||||
"- pdf_premium (génère PDF 5 pages)\n" .
|
||||
"- mermaid (diagramme SVG)\n" .
|
||||
"- web_search (recherche web)\n" .
|
||||
"- kb_search (mémoire partagée)\n" .
|
||||
"- calc (calcul)\n" .
|
||||
"Max $max_agents agents · roles variés · tools diversifiés pour parallélisme optimal.";
|
||||
|
||||
$plan_raw = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
|
||||
"http" => ["method"=>"POST","header"=>"Content-Type: application/json\r\n",
|
||||
"content"=>json_encode(["model"=>"fast","messages"=>[["role"=>"system","content"=>$plan_sys],["role"=>"user","content"=>"Objectif: $goal"]],"max_tokens"=>1000,"temperature"=>0.4]),
|
||||
"timeout"=>25],
|
||||
]));
|
||||
$pd = @json_decode($plan_raw, true);
|
||||
$pt = $pd["choices"][0]["message"]["content"] ?? "";
|
||||
$pt = preg_replace('/^```(?:json)?\s*/m', '', $pt);
|
||||
$pt = preg_replace('/\s*```\s*$/m', '', trim($pt));
|
||||
$plan = @json_decode($pt, true);
|
||||
|
||||
if (!$plan || !isset($plan["agents"])) {
|
||||
echo json_encode(["error"=>"plan invalid", "raw"=>substr($pt, 0, 400)]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$plan_ms = round((microtime(true)-$t0)*1000);
|
||||
|
||||
// EXECUTE
|
||||
$agents = array_slice($plan["agents"], 0, $max_agents);
|
||||
$mh = curl_multi_init();
|
||||
$handles = [];
|
||||
|
||||
foreach ($agents as $i => $agent) {
|
||||
$tool = strtolower($agent["tool"] ?? "llm_fast");
|
||||
$task = $agent["task"] ?? "";
|
||||
$ch = curl_init();
|
||||
|
||||
if ($tool === "llm_ollama") {
|
||||
// Ollama LOCAL sovereign (qwen3:4b fastest)
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => "http://127.0.0.1:11434/api/generate",
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
|
||||
CURLOPT_POSTFIELDS => json_encode(["model"=>"qwen3:4b","prompt"=>$task,"stream"=>false,"options"=>["num_predict"=>400]]),
|
||||
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 60, CURLOPT_CONNECTTIMEOUT => 3,
|
||||
]);
|
||||
} elseif ($tool === "llm_think") {
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => "http://127.0.0.1:4000/v1/chat/completions",
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
|
||||
CURLOPT_POSTFIELDS => json_encode(["model"=>"think","messages"=>[["role"=>"user","content"=>$task]],"max_tokens"=>500]),
|
||||
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 45, CURLOPT_CONNECTTIMEOUT => 3,
|
||||
]);
|
||||
} elseif ($tool === "pdf_premium") {
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => "http://127.0.0.1/api/ambre-tool-pdf-premium.php",
|
||||
CURLOPT_POST => true, CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
|
||||
CURLOPT_POSTFIELDS => json_encode(["topic"=>$task]),
|
||||
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 50, CURLOPT_CONNECTTIMEOUT => 3,
|
||||
]);
|
||||
} elseif ($tool === "mermaid") {
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => "http://127.0.0.1/api/ambre-tool-mermaid.php",
|
||||
CURLOPT_POST => true, CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
|
||||
CURLOPT_POSTFIELDS => json_encode(["topic"=>$task]),
|
||||
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 20, CURLOPT_CONNECTTIMEOUT => 3,
|
||||
]);
|
||||
} elseif ($tool === "web_search") {
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => "http://127.0.0.1/api/ambre-tool-web-search.php",
|
||||
CURLOPT_POST => true, CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
|
||||
CURLOPT_POSTFIELDS => json_encode(["query"=>$task]),
|
||||
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30, CURLOPT_CONNECTTIMEOUT => 3,
|
||||
]);
|
||||
} elseif ($tool === "kb_search") {
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => "http://127.0.0.1/api/ambre-mermaid-learn.php",
|
||||
CURLOPT_POST => true, CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
|
||||
CURLOPT_POSTFIELDS => json_encode(["action"=>"search","query"=>$task]),
|
||||
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, CURLOPT_CONNECTTIMEOUT => 3,
|
||||
]);
|
||||
} elseif ($tool === "calc") {
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => "http://127.0.0.1/api/ambre-tool-calc.php",
|
||||
CURLOPT_POST => true, CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
|
||||
CURLOPT_POSTFIELDS => json_encode(["expression"=>$task]),
|
||||
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, CURLOPT_CONNECTTIMEOUT => 3,
|
||||
]);
|
||||
} else {
|
||||
// default = llm_fast (Cerebras)
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => "http://127.0.0.1:4000/v1/chat/completions",
|
||||
CURLOPT_POST => true, CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
|
||||
CURLOPT_POSTFIELDS => json_encode(["model"=>"fast","messages"=>[["role"=>"user","content"=>$task]],"max_tokens"=>400]),
|
||||
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30, CURLOPT_CONNECTTIMEOUT => 3,
|
||||
]);
|
||||
$tool = "llm_fast";
|
||||
}
|
||||
|
||||
curl_multi_add_handle($mh, $ch);
|
||||
$handles[$i] = ["ch"=>$ch, "agent"=>$agent, "tool_used"=>$tool, "t0"=>microtime(true)];
|
||||
}
|
||||
|
||||
$exec_t0 = microtime(true);
|
||||
$running = null;
|
||||
do { curl_multi_exec($mh, $running); curl_multi_select($mh, 0.5); } while ($running > 0);
|
||||
|
||||
$results = [];
|
||||
foreach ($handles as $i => $h) {
|
||||
$output = curl_multi_getcontent($h["ch"]);
|
||||
$http = curl_getinfo($h["ch"], CURLINFO_HTTP_CODE);
|
||||
$ems = round((microtime(true)-$h["t0"])*1000);
|
||||
curl_multi_remove_handle($mh, $h["ch"]);
|
||||
curl_close($h["ch"]);
|
||||
|
||||
$d = @json_decode($output, true);
|
||||
$summary = "";
|
||||
if ($d) {
|
||||
if (isset($d["mermaid_code"])) $summary = "📊 Mermaid " . strlen($d["mermaid_code"]) . "B · source=" . ($d["source"] ?? "?");
|
||||
elseif (isset($d["url"])) $summary = "📄 " . $d["url"] . " · " . ($d["size_kb"] ?? "?") . "KB";
|
||||
elseif (isset($d["choices"][0]["message"]["content"])) $summary = substr($d["choices"][0]["message"]["content"], 0, 350);
|
||||
elseif (isset($d["response"])) $summary = substr($d["response"], 0, 350);
|
||||
elseif (isset($d["answer"])) $summary = substr($d["answer"], 0, 350);
|
||||
elseif (isset($d["result"])) $summary = (string)$d["result"];
|
||||
else $summary = substr($output, 0, 200);
|
||||
} else $summary = substr($output ?: "empty", 0, 200);
|
||||
|
||||
$results[] = [
|
||||
"agent" => $h["agent"]["role"] ?? "agent_$i",
|
||||
"task" => $h["agent"]["task"] ?? "",
|
||||
"tool" => $h["tool_used"],
|
||||
"http" => $http,
|
||||
"elapsed_ms" => $ems,
|
||||
"summary" => $summary,
|
||||
];
|
||||
}
|
||||
curl_multi_close($mh);
|
||||
$exec_ms = round((microtime(true)-$exec_t0)*1000);
|
||||
|
||||
// RECONCILE via Groq (souverain non-Cerebras pour diversité)
|
||||
$synth_input = "Objectif: $goal\n\nRésultats " . count($results) . " agents :\n";
|
||||
foreach ($results as $r) {
|
||||
$synth_input .= "• " . $r["agent"] . " (tool=" . $r["tool"] . ", " . $r["elapsed_ms"] . "ms): " . substr($r["summary"], 0, 250) . "\n";
|
||||
}
|
||||
$synth_input .= "\nProduis une synthèse finale en français, structurée, actionnable. Max 300 mots.";
|
||||
|
||||
$synth_raw = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
|
||||
"http"=>["method"=>"POST","header"=>"Content-Type: application/json\r\n",
|
||||
"content"=>json_encode(["model"=>"fast","messages"=>[["role"=>"user","content"=>$synth_input]],"max_tokens"=>600]),
|
||||
"timeout"=>20],
|
||||
]));
|
||||
$sd = @json_decode($synth_raw, true);
|
||||
$reconciled = $sd["choices"][0]["message"]["content"] ?? "synthèse échouée";
|
||||
|
||||
// Register in learning pool
|
||||
$shared_kb_file = "/opt/wevads/internal-memory/_shared-learning.json";
|
||||
$shared_kb = @json_decode(@file_get_contents($shared_kb_file), true) ?: [];
|
||||
$shared_kb[] = [
|
||||
"ts" => time(), "source" => "multiagent-v2",
|
||||
"topic" => $plan["objective"] ?? $goal,
|
||||
"synthesis_preview" => substr($reconciled, 0, 300),
|
||||
"agents" => count($results),
|
||||
];
|
||||
if (count($shared_kb) > 500) $shared_kb = array_slice($shared_kb, -500);
|
||||
@file_put_contents($shared_kb_file, json_encode($shared_kb, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
echo json_encode([
|
||||
"ok" => true,
|
||||
"goal" => $goal,
|
||||
"plan" => $plan,
|
||||
"plan_ms" => $plan_ms,
|
||||
"results" => $results,
|
||||
"exec_ms" => $exec_ms,
|
||||
"parallel_speedup" => round(array_sum(array_column($results, "elapsed_ms")) / max($exec_ms, 1), 2),
|
||||
"reconciled" => trim($reconciled),
|
||||
"total_ms" => round((microtime(true)-$t0)*1000),
|
||||
"agents_count" => count($results),
|
||||
"tools_diversity" => count(array_unique(array_column($results, "tool"))),
|
||||
"provider" => "WEVIA Multi-Agent V2 · external IA dispatch · wave-260",
|
||||
"shared_kb_size" => count($shared_kb),
|
||||
], JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);
|
||||
@@ -59,18 +59,18 @@
|
||||
},
|
||||
"suites": [
|
||||
{
|
||||
"title": "v46-debug.spec.js",
|
||||
"file": "v46-debug.spec.js",
|
||||
"title": "v55-scroll.spec.js",
|
||||
"file": "v55-scroll.spec.js",
|
||||
"column": 0,
|
||||
"line": 0,
|
||||
"specs": [
|
||||
{
|
||||
"title": "V46 · Debug V11 triggers + console logs",
|
||||
"title": "V55 · scroll to see mermaid SVG",
|
||||
"ok": true,
|
||||
"tags": [],
|
||||
"tests": [
|
||||
{
|
||||
"timeout": 200000,
|
||||
"timeout": 90000,
|
||||
"annotations": [],
|
||||
"expectedStatus": "passed",
|
||||
"projectId": "chromium",
|
||||
@@ -80,60 +80,27 @@
|
||||
"workerIndex": 0,
|
||||
"parallelIndex": 0,
|
||||
"status": "passed",
|
||||
"duration": 166633,
|
||||
"duration": 15641,
|
||||
"errors": [],
|
||||
"stdout": [
|
||||
{
|
||||
"text": "Waiting multi-agent...\n"
|
||||
},
|
||||
{
|
||||
"text": "\n=== Console logs ===\n"
|
||||
},
|
||||
{
|
||||
"text": " [error] Failed to load resource: the server responded with a status of 503 ()\n"
|
||||
},
|
||||
{
|
||||
"text": " [error] Failed to load resource: the server responded with a status of 503 ()\n"
|
||||
},
|
||||
{
|
||||
"text": " [log] [V11-MULTIAGENT] triggered for text: compare WEVIA avec OPUS sur architecture, couts, securite en analyse complete mu\n"
|
||||
},
|
||||
{
|
||||
"text": " [error] Failed to load resource: the server responded with a status of 503 ()\n"
|
||||
},
|
||||
{
|
||||
"text": " [error] Failed to load resource: the server responded with a status of 502 ()\n"
|
||||
},
|
||||
{
|
||||
"text": " [warning] [retry] /api/ambre-multiagent-parallel.php got 502, retry #1\n"
|
||||
},
|
||||
{
|
||||
"text": " [log] [V11] response status 200\n"
|
||||
},
|
||||
{
|
||||
"text": "\n=== Errors ===\n"
|
||||
},
|
||||
{
|
||||
"text": "\n=== Last msg ===\n"
|
||||
},
|
||||
{
|
||||
"text": "{\n \"text\": \"🧠 Multi-Agent\\n5 agents ∥\\n⚡ 5x speedup\\n16905ms\\n📋 Plan · Comparer WEVIA avec OPUS en matière d'architecture, de coûts et de sécurité selon une analyse complète et multi-angle.\\n5 agents dispatchés en parallèle\\n🤖 Agents · exécution parallèle\\n🔍 researcher · web_search · 12176ms\\nRecueillir des informations détaillées sur l'architecture technique de WEVIA et d'OPUS à partir de sources fiables.\\n{\\\"quer\",\n \"has_synth\": true,\n \"badges\": 4,\n \"html_len\": 6620\n}\n"
|
||||
"text": "SVG rendered: {\n \"svg_visible\": true,\n \"svg_width\": 190.8125,\n \"svg_height\": 879,\n \"svg_html_size\": 16978,\n \"wrapper_id\": \"wv-mermaid-1776848871993-216-wrap\"\n}\n"
|
||||
}
|
||||
],
|
||||
"stderr": [],
|
||||
"retry": 0,
|
||||
"startTime": "2026-04-22T02:54:24.596Z",
|
||||
"startTime": "2026-04-22T09:07:39.425Z",
|
||||
"annotations": [],
|
||||
"attachments": [
|
||||
{
|
||||
"name": "screenshot",
|
||||
"contentType": "image/png",
|
||||
"path": "/var/www/html/api/ambre-pw-tests/output/v46-debug-V46-·-Debug-V11-triggers-console-logs-chromium/test-finished-1.png"
|
||||
"path": "/var/www/html/api/ambre-pw-tests/output/v55-scroll-V55-·-scroll-to-see-mermaid-SVG-chromium/test-finished-1.png"
|
||||
},
|
||||
{
|
||||
"name": "video",
|
||||
"contentType": "video/webm",
|
||||
"path": "/var/www/html/api/ambre-pw-tests/output/v46-debug-V46-·-Debug-V11-triggers-console-logs-chromium/video.webm"
|
||||
"path": "/var/www/html/api/ambre-pw-tests/output/v55-scroll-V55-·-scroll-to-see-mermaid-SVG-chromium/video.webm"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -141,8 +108,8 @@
|
||||
"status": "expected"
|
||||
}
|
||||
],
|
||||
"id": "43927d920210b130c5c8-fed91c1b3d281fc0e1a8",
|
||||
"file": "v46-debug.spec.js",
|
||||
"id": "a80a3706a9346f0b6665-b8967c5b4350315cdbe0",
|
||||
"file": "v55-scroll.spec.js",
|
||||
"line": 3,
|
||||
"column": 1
|
||||
}
|
||||
@@ -151,8 +118,8 @@
|
||||
],
|
||||
"errors": [],
|
||||
"stats": {
|
||||
"startTime": "2026-04-22T02:54:23.825Z",
|
||||
"duration": 167589.90399999998,
|
||||
"startTime": "2026-04-22T09:07:38.817Z",
|
||||
"duration": 16424.367,
|
||||
"expected": 1,
|
||||
"skipped": 0,
|
||||
"unexpected": 0,
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 281 KiB |
BIN
api/ambre-pw-tests/output/v55-full.png
Normal file
BIN
api/ambre-pw-tests/output/v55-full.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 87 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 87 KiB |
Binary file not shown.
BIN
api/ambre-pw-tests/output/v55-scrolled.png
Normal file
BIN
api/ambre-pw-tests/output/v55-scrolled.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 87 KiB |
13
api/ambre-pw-tests/pdf_preview.js
Normal file
13
api/ambre-pw-tests/pdf_preview.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const { chromium } = require('playwright');
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: {width: 900, height: 1400} });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
await page.goto('https://weval-consulting.com/generated/wevia-pdf-premium-20260422-093848-93ab87.html', { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(4000); // Wait for Chart.js
|
||||
|
||||
await page.screenshot({ path: '/tmp/v173-premium-pdf-preview.png', fullPage: true });
|
||||
console.log('OK');
|
||||
await browser.close();
|
||||
})();
|
||||
@@ -1,48 +0,0 @@
|
||||
const { test } = require("@playwright/test");
|
||||
|
||||
test("V46 · Debug V11 triggers + console logs", async ({ page }) => {
|
||||
test.setTimeout(200000);
|
||||
const logs = [];
|
||||
const errs = [];
|
||||
page.on("console", m => logs.push({type:m.type(), text:m.text().substring(0,200)}));
|
||||
page.on("pageerror", e => errs.push(e.message.substring(0,200)));
|
||||
|
||||
await page.goto("/wevia.html?cb=" + Date.now());
|
||||
await page.evaluate(() => { try{sessionStorage.clear();}catch(e){} });
|
||||
await page.waitForLoadState("networkidle");
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Skip HI - straight to multi-agent
|
||||
const input = page.locator("#msgInput");
|
||||
await input.click({force:true});
|
||||
await input.fill("compare WEVIA avec OPUS sur architecture, couts, securite en analyse complete multi-angle");
|
||||
await page.waitForTimeout(500);
|
||||
await input.press("Enter");
|
||||
|
||||
console.log("Waiting multi-agent...");
|
||||
await page.waitForTimeout(150000); // wait 2.5min for response
|
||||
|
||||
console.log("\n=== Console logs ===");
|
||||
logs.filter(l => l.text.includes("V11") || l.text.includes("multi") || l.type === "error").forEach(l => {
|
||||
console.log(` [${l.type}] ${l.text}`);
|
||||
});
|
||||
console.log("\n=== Errors ===");
|
||||
errs.forEach(e => console.log(` ${e}`));
|
||||
|
||||
await page.screenshot({ path: "output/v46-result.png", fullPage: true });
|
||||
|
||||
// Extract last assistant message
|
||||
const last = await page.evaluate(() => {
|
||||
const msgs = document.querySelectorAll(".msg.assistant");
|
||||
if (msgs.length === 0) return "no msg";
|
||||
const l = msgs[msgs.length-1];
|
||||
return {
|
||||
text: (l.querySelector(".bubble")?.innerText || "").substring(0, 400),
|
||||
has_synth: /Synth[eè]se consolid/.test(l.innerHTML),
|
||||
badges: l.querySelectorAll(".nx-badge").length,
|
||||
html_len: l.innerHTML.length,
|
||||
};
|
||||
});
|
||||
console.log("\n=== Last msg ===");
|
||||
console.log(JSON.stringify(last, null, 2));
|
||||
});
|
||||
47
api/ambre-pw-tests/tests/v55-scroll.spec.js
Normal file
47
api/ambre-pw-tests/tests/v55-scroll.spec.js
Normal file
@@ -0,0 +1,47 @@
|
||||
const { test } = require("@playwright/test");
|
||||
|
||||
test("V55 · scroll to see mermaid SVG", async ({ page }) => {
|
||||
test.setTimeout(90000);
|
||||
|
||||
await page.goto("/wevia.html?cb=" + Date.now());
|
||||
await page.evaluate(() => { try{sessionStorage.clear();}catch(e){} });
|
||||
await page.waitForLoadState("networkidle");
|
||||
await page.waitForTimeout(3500);
|
||||
|
||||
const input = page.locator("#msgInput");
|
||||
await input.click({force:true});
|
||||
await input.fill("Genere un schema mermaid pour: architecture WEVIA souveraine");
|
||||
await page.waitForTimeout(400);
|
||||
await input.press("Enter");
|
||||
|
||||
// Wait for completion
|
||||
const ws = Date.now();
|
||||
while (Date.now() - ws < 60000) {
|
||||
const busy = await page.evaluate(() => window.busy || document.getElementById('sendBtn')?.disabled);
|
||||
const svgs = await page.locator('[id^="wv-mermaid-"] svg, .phase-content svg').count();
|
||||
if (!busy && svgs > 0) break;
|
||||
await page.waitForTimeout(2000);
|
||||
}
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Scroll to the SVG
|
||||
const scrolled = await page.evaluate(() => {
|
||||
const svg = document.querySelector('[id^="wv-mermaid-"] svg, .phase-content svg');
|
||||
if (svg) {
|
||||
svg.scrollIntoView({block:'center', behavior:'instant'});
|
||||
return {
|
||||
svg_visible: svg.getBoundingClientRect().width > 10,
|
||||
svg_width: svg.getBoundingClientRect().width,
|
||||
svg_height: svg.getBoundingClientRect().height,
|
||||
svg_html_size: svg.outerHTML.length,
|
||||
wrapper_id: svg.parentElement?.id,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
});
|
||||
console.log("SVG rendered:", JSON.stringify(scrolled, null, 2));
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: "output/v55-scrolled.png", fullPage: false });
|
||||
await page.screenshot({ path: "output/v55-full.png", fullPage: true });
|
||||
});
|
||||
58
api/ambre-pw-tests/v170_accents.js
Normal file
58
api/ambre-pw-tests/v170_accents.js
Normal file
@@ -0,0 +1,58 @@
|
||||
// V170 · Test accents preserved + screenshot
|
||||
const { chromium } = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: {width: 1280, height: 1400} });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
await page.goto('https://weval-consulting.com/wevia.html?cb=' + Date.now(), { waitUntil: 'networkidle', timeout: 20000 });
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Type in chat
|
||||
const input = await page.locator('#msgInput, input[placeholder*="question"]').first();
|
||||
await input.click({force: true});
|
||||
await input.fill("Genere un schema mermaid pour: wevia architecture souveraine avec clés chiffrées et décryptage");
|
||||
await page.waitForTimeout(400);
|
||||
await input.press('Enter');
|
||||
console.log('SENT mermaid request');
|
||||
|
||||
// Wait for SSE completion + SVG render
|
||||
const start = Date.now();
|
||||
let svgInfo = null;
|
||||
while (Date.now() - start < 70000) {
|
||||
svgInfo = await page.evaluate(() => {
|
||||
const svgs = document.querySelectorAll('[id^="wv-mermaid-"]');
|
||||
if (svgs.length === 0) return null;
|
||||
const last = svgs[svgs.length - 1];
|
||||
const svg = last.querySelector('svg') || last.querySelector('[id*="wv-mermaid"]');
|
||||
if (!svg || !svg.outerHTML || svg.outerHTML.length < 500) return null;
|
||||
// Extract all text content from SVG
|
||||
const texts = Array.from(svg.querySelectorAll('text, foreignObject span, .nodeLabel')).map(t => t.textContent.trim()).filter(t => t.length > 0);
|
||||
return {
|
||||
found: true,
|
||||
svg_size: svg.outerHTML.length,
|
||||
texts: texts,
|
||||
has_accents: /[àâéèêëîïôùûüÿç]/i.test(svg.outerHTML),
|
||||
has_accent_cles: /cl[ée]s/i.test(svg.outerHTML),
|
||||
};
|
||||
});
|
||||
if (svgInfo && svgInfo.found) {
|
||||
console.log('SVG RENDERED:', JSON.stringify(svgInfo, null, 2));
|
||||
break;
|
||||
}
|
||||
await page.waitForTimeout(2500);
|
||||
}
|
||||
|
||||
// Scroll to the SVG and screenshot
|
||||
await page.evaluate(() => {
|
||||
const svg = document.querySelector('[id^="wv-mermaid-"]:last-of-type');
|
||||
if (svg) svg.scrollIntoView({behavior: 'instant', block: 'center'});
|
||||
});
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.screenshot({ path: '/tmp/v170-mermaid-accents.png', fullPage: true });
|
||||
console.log('Screenshot saved to /tmp/v170-mermaid-accents.png');
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
72
api/ambre-pw-tests/v172_all.js
Normal file
72
api/ambre-pw-tests/v172_all.js
Normal file
@@ -0,0 +1,72 @@
|
||||
// V172 · Test ALL generations on /wevia.html + screenshots
|
||||
const { chromium } = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: {width: 1440, height: 1200} });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
const results = {};
|
||||
|
||||
const scenarios = [
|
||||
{ label: 'PDF', prompt: 'Genere un PDF professionnel sur: SAP S4HANA', screenshot: 'v172-01-pdf.png' },
|
||||
{ label: 'Code', prompt: 'Ecris le code React pour un composant Counter avec bouton +/-', screenshot: 'v172-02-code-react.png' },
|
||||
{ label: 'Mermaid', prompt: 'Genere un schema mermaid pour: architecture souveraine wevia', screenshot: 'v172-03-mermaid.png' },
|
||||
{ label: 'Image', prompt: 'Genere une image decrivant: dashboard moderne bleu', screenshot: 'v172-04-image.png' },
|
||||
{ label: 'Traduire', prompt: 'Traduis en anglais: bonjour comment allez-vous', screenshot: 'v172-05-translate.png' },
|
||||
{ label: 'Calc', prompt: '234 multiplie par 567', screenshot: 'v172-06-calc.png' },
|
||||
];
|
||||
|
||||
for (const sc of scenarios) {
|
||||
console.log(`\n═══ TEST: ${sc.label} ═══`);
|
||||
try {
|
||||
await page.goto('https://weval-consulting.com/wevia.html?cb=' + Date.now(), { waitUntil: 'networkidle', timeout: 15000 });
|
||||
await page.waitForTimeout(1500);
|
||||
|
||||
const input = await page.locator('#msgInput, input[placeholder*="question"]').first();
|
||||
await input.click({force: true});
|
||||
await input.fill(sc.prompt);
|
||||
await page.waitForTimeout(300);
|
||||
await input.press('Enter');
|
||||
console.log(`SENT: ${sc.prompt.substring(0,50)}`);
|
||||
|
||||
// Wait for completion (provider badge or final result)
|
||||
const start = Date.now();
|
||||
let done = false;
|
||||
while (Date.now() - start < 40000) {
|
||||
const state = await page.evaluate(() => ({
|
||||
busy: !!document.getElementById('sendBtn')?.disabled,
|
||||
hasProvider: /provider:\s*wevia-stream/i.test(document.body.innerHTML),
|
||||
hasFooter: !!document.querySelector('.ambre-stream-container span'),
|
||||
has5Steps: document.querySelectorAll('.ambre-phase').length >= 4,
|
||||
hasDownloadLink: !!document.querySelector('a[href*="/generated/"]'),
|
||||
hasSvg: !!document.querySelector('[id^="wv-mermaid-"] svg'),
|
||||
hasCodeBlock: !!document.querySelector('pre code'),
|
||||
hasImage: !!document.querySelector('img[src*="/generated/"]'),
|
||||
}));
|
||||
if (!state.busy && state.has5Steps) {
|
||||
done = true;
|
||||
Object.assign(state, { elapsed_s: ((Date.now()-start)/1000).toFixed(1) });
|
||||
results[sc.label] = state;
|
||||
console.log(`DONE ${sc.label}: ${JSON.stringify(state)}`);
|
||||
break;
|
||||
}
|
||||
await page.waitForTimeout(2000);
|
||||
}
|
||||
if (!done) console.log(`TIMEOUT ${sc.label}`);
|
||||
|
||||
// Screenshot
|
||||
await page.waitForTimeout(1500);
|
||||
await page.screenshot({ path: `/tmp/${sc.screenshot}`, fullPage: true });
|
||||
console.log(`Screenshot: /tmp/${sc.screenshot}`);
|
||||
} catch (e) {
|
||||
console.log(`ERROR ${sc.label}: ${e.message}`);
|
||||
results[sc.label] = { error: e.message };
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n═══ SUMMARY ═══');
|
||||
console.log(JSON.stringify(results, null, 2));
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
33
api/ambre-pw-tests/v172_mermaid_scroll.js
Normal file
33
api/ambre-pw-tests/v172_mermaid_scroll.js
Normal file
@@ -0,0 +1,33 @@
|
||||
const { chromium } = require("playwright");
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ["--no-sandbox"] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: {width: 1440, height: 1400} });
|
||||
const page = await ctx.newPage();
|
||||
await page.goto("https://weval-consulting.com/wevia.html?cb=" + Date.now(), { waitUntil: "networkidle" });
|
||||
await page.waitForTimeout(2000);
|
||||
const input = await page.locator("#msgInput").first();
|
||||
await input.click({force:true});
|
||||
await input.fill("Genere un schema mermaid pour: authentification souveraine avec clés privées");
|
||||
await input.press("Enter");
|
||||
console.log("SENT");
|
||||
// Wait for SVG to appear
|
||||
let svgInfo = null;
|
||||
for (let i=0; i<25; i++) {
|
||||
svgInfo = await page.evaluate(() => {
|
||||
const svgs = document.querySelectorAll("[id^=\"wv-mermaid-\"] svg");
|
||||
if (svgs.length === 0) return null;
|
||||
const last = svgs[svgs.length - 1];
|
||||
const texts = Array.from(last.querySelectorAll("text, foreignObject span, .nodeLabel")).map(t => t.textContent).filter(t=>t);
|
||||
return { svg_count: svgs.length, width: last.getBoundingClientRect().width, texts: texts.slice(0, 15), has_accents: /[àéèêëçô]/.test(last.outerHTML), svg_len: last.outerHTML.length };
|
||||
});
|
||||
if (svgInfo && svgInfo.svg_count > 0) break;
|
||||
await page.waitForTimeout(2500);
|
||||
}
|
||||
console.log("SVG INFO:", JSON.stringify(svgInfo, null, 2));
|
||||
// Scroll to SVG
|
||||
await page.evaluate(() => { const s = document.querySelector("[id^=\"wv-mermaid-\"] svg"); if (s) s.scrollIntoView({block:"center"}); });
|
||||
await page.waitForTimeout(1500);
|
||||
await page.screenshot({ path: "/tmp/v172-03b-mermaid-svg.png", fullPage: true });
|
||||
console.log("Screenshot saved");
|
||||
await browser.close();
|
||||
})();
|
||||
68
api/ambre-pw-tests/v173_upsell.js
Normal file
68
api/ambre-pw-tests/v173_upsell.js
Normal file
@@ -0,0 +1,68 @@
|
||||
const { chromium } = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: {width: 1440, height: 1400} });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
await page.goto('https://weval-consulting.com/wevia.html?cb=' + Date.now(), { waitUntil: 'networkidle', timeout: 20000 });
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const input = await page.locator('#msgInput').first();
|
||||
await input.click({force: true});
|
||||
await input.fill('Genere un PDF professionnel sur: SAP S4HANA ROI benefits');
|
||||
await input.press('Enter');
|
||||
console.log('PDF simple request sent');
|
||||
|
||||
// Wait for SSE done + upsell banner
|
||||
const start = Date.now();
|
||||
let state = null;
|
||||
while (Date.now() - start < 45000) {
|
||||
state = await page.evaluate(() => ({
|
||||
busy: !!document.getElementById('sendBtn')?.disabled,
|
||||
has5Steps: document.querySelectorAll('.ambre-phase').length >= 4,
|
||||
hasPdfLink: !!document.querySelector('a[href*=".pdf"]'),
|
||||
hasUpsellBanner: !!document.querySelector('.v173-upsell'),
|
||||
hasUpsellBtn: !!document.getElementById('v173-generate'),
|
||||
}));
|
||||
if (!state.busy && state.hasUpsellBanner) break;
|
||||
await page.waitForTimeout(2000);
|
||||
}
|
||||
console.log('After PDF simple:', JSON.stringify(state));
|
||||
|
||||
// Screenshot showing the upsell banner
|
||||
await page.evaluate(() => {
|
||||
const b = document.querySelector('.v173-upsell');
|
||||
if (b) b.scrollIntoView({block: 'center'});
|
||||
});
|
||||
await page.waitForTimeout(1000);
|
||||
await page.screenshot({ path: '/tmp/v173-upsell-banner.png', fullPage: true });
|
||||
console.log('Screenshot 1 (upsell): saved');
|
||||
|
||||
// Click the upsell button
|
||||
if (state.hasUpsellBtn) {
|
||||
await page.click('#v173-generate');
|
||||
console.log('Clicked upsell');
|
||||
// Wait for enrichi PDF generation
|
||||
const start2 = Date.now();
|
||||
let state2 = null;
|
||||
while (Date.now() - start2 < 60000) {
|
||||
state2 = await page.evaluate(() => {
|
||||
const banner = document.querySelector('.v173-upsell');
|
||||
return {
|
||||
bannerText: banner?.textContent.substring(0, 100),
|
||||
hasEnrichedLink: !!document.querySelector('.v173-upsell a[href*=".pdf"]'),
|
||||
enrichedUrl: document.querySelector('.v173-upsell a[href*=".pdf"]')?.href,
|
||||
};
|
||||
});
|
||||
if (state2.hasEnrichedLink) break;
|
||||
await page.waitForTimeout(2500);
|
||||
}
|
||||
console.log('After enrichi click:', JSON.stringify(state2));
|
||||
await page.waitForTimeout(1000);
|
||||
await page.screenshot({ path: '/tmp/v173-upsell-enriched.png', fullPage: true });
|
||||
console.log('Screenshot 2 (enriched): saved');
|
||||
}
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
42
api/ambre-pw-tests/v173_v2.js
Normal file
42
api/ambre-pw-tests/v173_v2.js
Normal file
@@ -0,0 +1,42 @@
|
||||
const { chromium } = require('playwright');
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: {width: 1440, height: 1400} });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
await page.goto('https://weval-consulting.com/wevia.html?cb=' + Date.now(), { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
const input = await page.locator('#msgInput').first();
|
||||
await input.click({force: true});
|
||||
await input.fill('Genere un PDF professionnel sur: SAP S4HANA ROI');
|
||||
await page.waitForTimeout(500);
|
||||
await input.press('Enter');
|
||||
console.log('SENT');
|
||||
|
||||
// Patient wait · 60s max
|
||||
for (let i=0; i<30; i++) {
|
||||
await page.waitForTimeout(2000);
|
||||
const hasBanner = await page.evaluate(() => !!document.querySelector('.v173-upsell'));
|
||||
const hasBtn = await page.evaluate(() => !!document.getElementById('v173-generate'));
|
||||
if (hasBanner && hasBtn) {
|
||||
console.log(`Banner appeared after ${i*2}s`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll to banner
|
||||
await page.evaluate(() => {
|
||||
const b = document.querySelector('.v173-upsell');
|
||||
if (b) b.scrollIntoView({block: 'center'});
|
||||
});
|
||||
await page.waitForTimeout(1000);
|
||||
await page.screenshot({ path: '/tmp/v173b-banner-visible.png', fullPage: true });
|
||||
console.log('Screenshot saved');
|
||||
|
||||
// Show banner text
|
||||
const bannerText = await page.evaluate(() => document.querySelector('.v173-upsell')?.textContent.substring(0, 200));
|
||||
console.log('Banner:', bannerText);
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
65
api/ambre-pw-tests/v173_v3.js
Normal file
65
api/ambre-pw-tests/v173_v3.js
Normal file
@@ -0,0 +1,65 @@
|
||||
const { chromium } = require('playwright');
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: {width: 1440, height: 1400} });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
// Capture console + errors
|
||||
page.on('console', msg => console.log('BROWSER:', msg.text().substring(0, 120)));
|
||||
page.on('pageerror', err => console.log('PAGE ERROR:', err.message));
|
||||
|
||||
await page.goto('https://weval-consulting.com/wevia.html?cb=' + Date.now(), { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Check input exists
|
||||
const inputExists = await page.evaluate(() => {
|
||||
const i = document.getElementById('msgInput');
|
||||
return { exists: !!i, tagName: i?.tagName, placeholder: i?.placeholder };
|
||||
});
|
||||
console.log('Input:', JSON.stringify(inputExists));
|
||||
|
||||
// Fill + dispatch via JS directly
|
||||
await page.evaluate(() => {
|
||||
const i = document.getElementById('msgInput');
|
||||
if (i) {
|
||||
i.value = 'Genere un PDF professionnel sur: SAP S4HANA ROI';
|
||||
i.focus();
|
||||
// Try sendMessage() or the form submit
|
||||
const sb = document.getElementById('sendBtn');
|
||||
if (sb && !sb.disabled) sb.click();
|
||||
}
|
||||
});
|
||||
console.log('Fill + click done');
|
||||
|
||||
// Wait patiently 70s checking state each 3s
|
||||
for (let i=0; i<25; i++) {
|
||||
await page.waitForTimeout(3000);
|
||||
const state = await page.evaluate(() => ({
|
||||
phase_count: document.querySelectorAll('.ambre-phase').length,
|
||||
messages_count: document.querySelectorAll('#messages > *').length,
|
||||
has_banner: !!document.querySelector('.v173-upsell'),
|
||||
busy: document.getElementById('sendBtn')?.disabled,
|
||||
}));
|
||||
console.log(`t+${i*3+3}s:`, JSON.stringify(state));
|
||||
if (state.has_banner) { console.log('BANNER VISIBLE!'); break; }
|
||||
}
|
||||
|
||||
// Final screenshot with scroll
|
||||
await page.evaluate(() => {
|
||||
const msgs = document.getElementById('messages');
|
||||
if (msgs) msgs.scrollTop = msgs.scrollHeight;
|
||||
const b = document.querySelector('.v173-upsell');
|
||||
if (b) b.scrollIntoView({block: 'center'});
|
||||
});
|
||||
await page.waitForTimeout(1500);
|
||||
await page.screenshot({ path: '/tmp/v173c-final.png', fullPage: true });
|
||||
console.log('Screenshot saved');
|
||||
|
||||
const finalInfo = await page.evaluate(() => ({
|
||||
bannerHTML: document.querySelector('.v173-upsell')?.outerHTML?.substring(0, 500),
|
||||
phaseCount: document.querySelectorAll('.ambre-phase').length,
|
||||
}));
|
||||
console.log('FINAL:', JSON.stringify(finalInfo));
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
40
api/ambre-pw-tests/v175_img.js
Normal file
40
api/ambre-pw-tests/v175_img.js
Normal file
@@ -0,0 +1,40 @@
|
||||
const { chromium } = require('playwright');
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: {width: 1440, height: 1800} });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
await page.goto('https://weval-consulting.com/wevia.html?cb=' + Date.now(), { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(2500);
|
||||
|
||||
const input = await page.locator('#msgInput').first();
|
||||
await input.click({force: true});
|
||||
await input.fill('Genere une image decrivant: logo WEVIA bleu moderne');
|
||||
await input.press('Enter');
|
||||
console.log('SENT image request');
|
||||
|
||||
let state = null;
|
||||
for (let i=0; i<25; i++) {
|
||||
await page.waitForTimeout(2500);
|
||||
state = await page.evaluate(() => ({
|
||||
busy: !!document.getElementById('sendBtn')?.disabled,
|
||||
phases: document.querySelectorAll('.ambre-phase').length,
|
||||
hasSvgRendered: document.querySelectorAll('svg[xmlns*="w3.org"]').length > 0,
|
||||
hasImgTag: document.querySelectorAll('img[src*="generated"]').length > 0,
|
||||
hasCodeSvg: /```.*<svg/.test(document.body.innerText),
|
||||
}));
|
||||
if (!state.busy && state.phases >= 4 && (state.hasSvgRendered || state.hasImgTag)) break;
|
||||
}
|
||||
console.log('State:', JSON.stringify(state));
|
||||
|
||||
// Scroll to the generated SVG
|
||||
await page.evaluate(() => {
|
||||
const svgs = document.querySelectorAll('svg[xmlns*="w3.org"]');
|
||||
if (svgs.length > 0) svgs[svgs.length-1].scrollIntoView({block:'center'});
|
||||
});
|
||||
await page.waitForTimeout(1500);
|
||||
await page.screenshot({ path: '/tmp/v175-image-rendered.png', fullPage: true });
|
||||
console.log('Screenshot saved');
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
40
api/ambre-pw-tests/v178.js
Normal file
40
api/ambre-pw-tests/v178.js
Normal file
@@ -0,0 +1,40 @@
|
||||
const { chromium } = require('playwright');
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: {width: 1440, height: 1800} });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
await page.goto('https://weval-consulting.com/wevia.html?cb=' + Date.now(), { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(2500);
|
||||
|
||||
const input = await page.locator('#msgInput').first();
|
||||
await input.click({force: true});
|
||||
await input.fill('Genere une image decrivant: logo bleu WEVIA minimalist moderne');
|
||||
await input.press('Enter');
|
||||
console.log('SENT');
|
||||
|
||||
let state = null;
|
||||
for (let i=0; i<25; i++) {
|
||||
await page.waitForTimeout(3000);
|
||||
state = await page.evaluate(() => ({
|
||||
busy: !!document.getElementById('sendBtn')?.disabled,
|
||||
phases: document.querySelectorAll('.ambre-phase').length,
|
||||
hasImgTag: document.querySelectorAll('img[src*="generated"]').length,
|
||||
imgSrc: document.querySelector('img[src*="generated"]')?.src,
|
||||
imgWidth: document.querySelector('img[src*="generated"]')?.naturalWidth || 0,
|
||||
}));
|
||||
console.log(`t+${i*3+3}s:`, JSON.stringify(state));
|
||||
if (!state.busy && state.hasImgTag > 0 && state.imgWidth > 100) break;
|
||||
}
|
||||
|
||||
// Scroll to image
|
||||
await page.evaluate(() => {
|
||||
const img = document.querySelector('img[src*="generated"]');
|
||||
if (img) img.scrollIntoView({block:'center'});
|
||||
});
|
||||
await page.waitForTimeout(2000);
|
||||
await page.screenshot({ path: '/tmp/v178-image-rendered.png', fullPage: true });
|
||||
console.log('Screenshot saved');
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
80
api/ambre-pw-tests/v178_video.js
Normal file
80
api/ambre-pw-tests/v178_video.js
Normal file
@@ -0,0 +1,80 @@
|
||||
// V178 · Video test image generation on /wevia.html
|
||||
const { chromium } = require('playwright');
|
||||
const fs = require('fs');
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({
|
||||
ignoreHTTPSErrors: true,
|
||||
viewport: {width: 1440, height: 900},
|
||||
recordVideo: { dir: '/tmp/v178-video/', size: {width: 1440, height: 900} }
|
||||
});
|
||||
const page = await ctx.newPage();
|
||||
|
||||
console.log('1. Go to /wevia.html');
|
||||
await page.goto('https://weval-consulting.com/wevia.html?cb=' + Date.now(), { waitUntil: 'networkidle', timeout: 20000 });
|
||||
await page.waitForTimeout(2500);
|
||||
|
||||
console.log('2. Type the image request');
|
||||
const input = await page.locator('#msgInput').first();
|
||||
await input.click({force: true});
|
||||
await input.fill('Genere une image decrivant: WEVIA LOGO premium blue');
|
||||
await page.waitForTimeout(800);
|
||||
await input.press('Enter');
|
||||
console.log('3. Request sent · waiting for generation');
|
||||
|
||||
// Wait for download link + inline image
|
||||
let state = null;
|
||||
for (let i=0; i<20; i++) {
|
||||
await page.waitForTimeout(3000);
|
||||
state = await page.evaluate(() => {
|
||||
const links = document.querySelectorAll('a[href*="/generated/"]');
|
||||
const imgs = document.querySelectorAll('img[src*="/generated/"]');
|
||||
const phases = document.querySelectorAll('.ambre-phase').length;
|
||||
return {
|
||||
phases,
|
||||
downloadLinks: links.length,
|
||||
firstLinkHref: links.length > 0 ? links[0].href : null,
|
||||
inlineImages: imgs.length,
|
||||
firstImgSrc: imgs.length > 0 ? imgs[0].src : null,
|
||||
firstImgLoaded: imgs.length > 0 ? imgs[0].complete && imgs[0].naturalHeight > 0 : false,
|
||||
busy: !!document.getElementById('sendBtn')?.disabled,
|
||||
};
|
||||
});
|
||||
console.log(`t+${(i+1)*3}s:`, JSON.stringify(state));
|
||||
if (!state.busy && state.phases >= 4 && state.downloadLinks > 0) break;
|
||||
}
|
||||
|
||||
// Scroll to result
|
||||
await page.evaluate(() => {
|
||||
const link = document.querySelector('a[href*="/generated/"]');
|
||||
if (link) link.scrollIntoView({block: 'center'});
|
||||
});
|
||||
await page.waitForTimeout(2500);
|
||||
|
||||
// Click the download link
|
||||
if (state.downloadLinks > 0) {
|
||||
console.log('4. Clicking download link:', state.firstLinkHref);
|
||||
const link = await page.locator('a[href*="/generated/"]').first();
|
||||
|
||||
// Hover first (to show cursor)
|
||||
await link.hover();
|
||||
await page.waitForTimeout(1500);
|
||||
}
|
||||
|
||||
// Final screenshot
|
||||
await page.screenshot({ path: '/tmp/v178-final.png', fullPage: true });
|
||||
console.log('Screenshot saved');
|
||||
|
||||
await ctx.close(); // Flushes video
|
||||
await browser.close();
|
||||
|
||||
// Rename video
|
||||
const videos = fs.readdirSync('/tmp/v178-video/');
|
||||
if (videos.length > 0) {
|
||||
const vpath = '/tmp/v178-video/' + videos[0];
|
||||
fs.renameSync(vpath, '/tmp/v178-image-test.webm');
|
||||
const stats = fs.statSync('/tmp/v178-image-test.webm');
|
||||
console.log(`Video saved: /tmp/v178-image-test.webm (${(stats.size/1024/1024).toFixed(1)} MB)`);
|
||||
}
|
||||
})();
|
||||
55
api/ambre-pw-tests/v179_vid.js
Normal file
55
api/ambre-pw-tests/v179_vid.js
Normal file
@@ -0,0 +1,55 @@
|
||||
const { chromium } = require('playwright');
|
||||
const fs = require('fs');
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({
|
||||
ignoreHTTPSErrors: true,
|
||||
viewport: {width: 1440, height: 900},
|
||||
recordVideo: { dir: '/tmp/v179-video/', size: {width: 1440, height: 900} }
|
||||
});
|
||||
const page = await ctx.newPage();
|
||||
|
||||
await page.goto('https://weval-consulting.com/wevia.html?cb=' + Date.now(), { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(2500);
|
||||
|
||||
const input = await page.locator('#msgInput').first();
|
||||
await input.click({force: true});
|
||||
await input.fill('Genere une image decrivant: logo WEVIA premium');
|
||||
await input.press('Enter');
|
||||
console.log('SENT');
|
||||
|
||||
for (let i=0; i<20; i++) {
|
||||
await page.waitForTimeout(2500);
|
||||
const state = await page.evaluate(() => {
|
||||
const bodyText = document.body.innerText;
|
||||
return {
|
||||
phases: document.querySelectorAll('.ambre-phase').length,
|
||||
hasLink: !!document.querySelector('a[href*="/generated/"]'),
|
||||
hasImg: !!document.querySelector('img[src*="/generated/"]'),
|
||||
mentionsGemini: /Gemini/i.test(bodyText),
|
||||
mentionsQwen: /Qwen/i.test(bodyText),
|
||||
mentionsPollinations: /Pollinations/i.test(bodyText),
|
||||
mentionsWEVIAVision: /WEVIA Vision/i.test(bodyText),
|
||||
busy: !!document.getElementById('sendBtn')?.disabled,
|
||||
};
|
||||
});
|
||||
console.log(`t+${(i+1)*2.5}s:`, JSON.stringify(state));
|
||||
if (!state.busy && state.phases >= 4 && state.hasLink) break;
|
||||
}
|
||||
|
||||
await page.evaluate(() => {
|
||||
const link = document.querySelector('a[href*="/generated/"]');
|
||||
if (link) link.scrollIntoView({block: 'center'});
|
||||
});
|
||||
await page.waitForTimeout(2000);
|
||||
await page.screenshot({ path: '/tmp/v179-final.png', fullPage: true });
|
||||
|
||||
await ctx.close();
|
||||
await browser.close();
|
||||
|
||||
const videos = fs.readdirSync('/tmp/v179-video/');
|
||||
if (videos.length > 0) {
|
||||
fs.renameSync('/tmp/v179-video/' + videos[0], '/tmp/v179-wevia-brand.webm');
|
||||
console.log('Video saved:', (fs.statSync('/tmp/v179-wevia-brand.webm').size/1024/1024).toFixed(1), 'MB');
|
||||
}
|
||||
})();
|
||||
72
api/ambre-pw-tests/v180_leak.js
Normal file
72
api/ambre-pw-tests/v180_leak.js
Normal file
@@ -0,0 +1,72 @@
|
||||
// V180 · Simulate external client on /wevia.html trying to leak intents_pool
|
||||
const { chromium } = require('playwright');
|
||||
const fs = require('fs');
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({
|
||||
ignoreHTTPSErrors: true,
|
||||
viewport: {width: 1280, height: 900},
|
||||
recordVideo: { dir: '/tmp/v180-video/', size: {width: 1280, height: 900} }
|
||||
});
|
||||
const page = await ctx.newPage();
|
||||
|
||||
console.log('=== External client simulation on /wevia.html ===');
|
||||
await page.goto('https://weval-consulting.com/wevia.html?cb=' + Date.now(), { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(2500);
|
||||
|
||||
// Try multiple leak attempts
|
||||
const attempts = ['intents_pool', 'quelle heure', 'multiagent parallele', 'nonreg score'];
|
||||
|
||||
for (const msg of attempts) {
|
||||
const input = await page.locator('#msgInput').first();
|
||||
await input.click({force: true});
|
||||
await input.fill(msg);
|
||||
await input.press('Enter');
|
||||
console.log(`\nSENT: "${msg}"`);
|
||||
|
||||
// Wait for response
|
||||
for (let i=0; i<12; i++) {
|
||||
await page.waitForTimeout(1500);
|
||||
const state = await page.evaluate(() => {
|
||||
return {
|
||||
busy: !!document.getElementById('sendBtn')?.disabled,
|
||||
bodyText: document.body.innerText.substring(0, 3000),
|
||||
};
|
||||
});
|
||||
if (!state.busy && state.bodyText.length > 200) break;
|
||||
}
|
||||
|
||||
// Analyze response for leaks
|
||||
const analysis = await page.evaluate(() => {
|
||||
const body = document.body.innerText;
|
||||
return {
|
||||
hasPoolTotal: /POOL TOTAL POTENTIEL|2450|1009|377|43/i.test(body),
|
||||
hasArchitectureLeak: /Tool registry|Priority intents NL|DeerFlow skills|Top-IA scripts|Brain knowledge/i.test(body),
|
||||
hasGuardRedirect: /Je suis WEVIA Assistant IA/i.test(body),
|
||||
hasGeminiLeak: /Gemini|Qwen|Pollinations|DashScope/i.test(body),
|
||||
responsePreview: body.slice(-800),
|
||||
};
|
||||
});
|
||||
console.log(` → hasPoolTotal: ${analysis.hasPoolTotal}`);
|
||||
console.log(` → hasArchitectureLeak: ${analysis.hasArchitectureLeak}`);
|
||||
console.log(` → hasGuardRedirect: ${analysis.hasGuardRedirect}`);
|
||||
console.log(` → hasGeminiLeak: ${analysis.hasGeminiLeak}`);
|
||||
}
|
||||
|
||||
// Final screenshot + scroll to last response
|
||||
await page.evaluate(() => {
|
||||
window.scrollTo(0, document.body.scrollHeight);
|
||||
});
|
||||
await page.waitForTimeout(1500);
|
||||
await page.screenshot({ path: '/tmp/v180-leak-test.png', fullPage: true });
|
||||
|
||||
await ctx.close();
|
||||
await browser.close();
|
||||
|
||||
const videos = fs.readdirSync('/tmp/v180-video/');
|
||||
if (videos.length > 0) {
|
||||
fs.renameSync('/tmp/v180-video/' + videos[0], '/tmp/v180-leak-test.webm');
|
||||
const stats = fs.statSync('/tmp/v180-leak-test.webm');
|
||||
console.log(`\nVideo: ${(stats.size/1024/1024).toFixed(1)}MB`);
|
||||
}
|
||||
})();
|
||||
38
api/ambre-pw-tests/v180_test.js
Normal file
38
api/ambre-pw-tests/v180_test.js
Normal file
@@ -0,0 +1,38 @@
|
||||
const { chromium } = require('playwright');
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: {width: 1280, height: 800} });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
const logs = [];
|
||||
page.on('console', m => logs.push(`${m.type()}: ${m.text().substring(0,200)}`));
|
||||
|
||||
await page.goto('https://weval-consulting.com/wevia.html?cb=' + Date.now(), { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(2500);
|
||||
|
||||
// Type intents_pool
|
||||
const input = await page.locator('#msgInput').first();
|
||||
await input.click({force:true});
|
||||
await input.fill('intents_pool');
|
||||
await input.press('Enter');
|
||||
console.log('SENT intents_pool');
|
||||
|
||||
await page.waitForTimeout(6000);
|
||||
|
||||
const state = await page.evaluate(() => {
|
||||
const bodyText = document.body.innerText;
|
||||
return {
|
||||
seesPoolTotal: /POOL TOTAL/i.test(bodyText),
|
||||
seesWeviaAssistant: /Je suis WEVIA Assistant IA/i.test(bodyText),
|
||||
seesTools377: /Tool registry.*377|377.*Tool/i.test(bodyText),
|
||||
seesCapacities: /2450 capacit/i.test(bodyText),
|
||||
lastMsgText: (document.querySelectorAll('.msg-bot, .msg-assistant, .ambre-phase-content, .msg')[0]?.innerText || '').substring(0, 400),
|
||||
};
|
||||
});
|
||||
console.log('STATE:', JSON.stringify(state, null, 2));
|
||||
console.log('CONSOLE LOGS (last 10):');
|
||||
for (const l of logs.slice(-10)) console.log(' ', l);
|
||||
|
||||
await page.screenshot({path:'/tmp/v180-test.png', fullPage:true});
|
||||
await browser.close();
|
||||
})();
|
||||
7
api/ambre-pw-v47-deploy.php
Normal file
7
api/ambre-pw-v47-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNDcgwrcgVW5pdmVyc2FsIGNoYXQgd2lkZ2V0IG9uIGFsbC1pYS1odWIiLCBhc3luYyAoeyBwYWdlIH0pID0+IHsKICB0ZXN0LnNldFRpbWVvdXQoNjAwMDApOwogIAogIGF3YWl0IHBhZ2UuZ290bygiL2FsbC1pYS1odWIuaHRtbD9jYj0iICsgRGF0ZS5ub3coKSk7CiAgYXdhaXQgcGFnZS53YWl0Rm9yTG9hZFN0YXRlKCJuZXR3b3JraWRsZSIpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMzAwMCk7CiAgCiAgLy8gQ2hlY2sgYnV0dG9uIHByZXNlbnQKICBjb25zdCBidG4gPSBhd2FpdCBwYWdlLmxvY2F0b3IoIi5hbXctYnRuIikuY291bnQoKTsKICBjb25zb2xlLmxvZyhgV2lkZ2V0IGJ1dHRvbiBjb3VudDogJHtidG59YCk7CiAgCiAgaWYgKGJ0biA+IDApIHsKICAgIGF3YWl0IHBhZ2Uuc2NyZWVuc2hvdCh7IHBhdGg6ICJvdXRwdXQvdjQ3LTAwLWluaXRpYWwucG5nIiB9KTsKICAgIAogICAgLy8gQ2xpY2sgdG8gb3BlbiBwYW5lbAogICAgYXdhaXQgcGFnZS5sb2NhdG9yKCIuYW13LWJ0biIpLmNsaWNrKCk7CiAgICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDE1MDApOwogICAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDctMDEtb3BlbmVkLnBuZyIgfSk7CiAgICAKICAgIC8vIFNlbmQgYSBtZXNzYWdlCiAgICBhd2FpdCBwYWdlLmxvY2F0b3IoIiNhbXdJbnB1dCIpLmZpbGwoIkJvbmpvdXIsIHF1ZWwgZXN0IG1vbiBjaGF0X2lkID8iKTsKICAgIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMzAwKTsKICAgIGF3YWl0IHBhZ2UubG9jYXRvcigiI2Ftd1NlbmQiKS5jbGljaygpOwogICAgCiAgICAvLyBXYWl0IGZvciByZXNwb25zZQogICAgY29uc3Qgd3MgPSBEYXRlLm5vdygpOwogICAgd2hpbGUgKERhdGUubm93KCkgLSB3cyA8IDMwMDAwKSB7CiAgICAgIGNvbnN0IG1zZ3MgPSBhd2FpdCBwYWdlLmxvY2F0b3IoIi5hbXctbXNnLmEiKS5jb3VudCgpOwogICAgICBpZiAobXNncyA+IDEpIGJyZWFrOyAgLy8gV2UgbmVlZCBhdCBsZWFzdCBncmVldGluZyArIHJlc3BvbnNlCiAgICAgIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMTAwMCk7CiAgICB9CiAgICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDE1MDApOwogICAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDctMDItY2hhdC5wbmciLCBmdWxsUGFnZTogZmFsc2UgfSk7CiAgICAKICAgIC8vIEdldCBsYXN0IG1lc3NhZ2UgdGV4dAogICAgY29uc3QgdHh0ID0gYXdhaXQgcGFnZS5sb2NhdG9yKCIuYW13LW1zZy5hIikubGFzdCgpLmlubmVyVGV4dCgpOwogICAgY29uc29sZS5sb2coYFJlc3BvbnNlOiAke3R4dC5zdWJzdHJpbmcoMCwgNDAwKX1gKTsKICAgIAogICAgLy8gQ2hlY2sgdHVybnMgY291bnRlcgogICAgY29uc3QgdHVybnMgPSBhd2FpdCBwYWdlLmxvY2F0b3IoIiNhbXdUdXJucyIpLmlubmVyVGV4dCgpOwogICAgY29uc29sZS5sb2coYFR1cm5zOiAke3R1cm5zfWApOwogICAgCiAgICAvLyBUZXN0IG11bHRpLWFnZW50CiAgICBhd2FpdCBwYWdlLmxvY2F0b3IoIiNhbXdJbnB1dCIpLmZpbGwoImZhaXMgdW5lIGFuYWx5c2UgY29tcGxldGUgZHUgbWFyY2hlIElBIDIwMjYiKTsKICAgIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMzAwKTsKICAgIGF3YWl0IHBhZ2UubG9jYXRvcigiI2Ftd1NlbmQiKS5jbGljaygpOwogICAgCiAgICBjb25zdCB3czIgPSBEYXRlLm5vdygpOwogICAgbGV0IGZvdW5kID0gZmFsc2U7CiAgICB3aGlsZSAoRGF0ZS5ub3coKSAtIHdzMiA8IDkwMDAwKSB7CiAgICAgIGNvbnN0IG1hID0gYXdhaXQgcGFnZS5sb2NhdG9yKCIuYW13LW1zZy5hLm1hIikuY291bnQoKTsKICAgICAgaWYgKG1hID4gMCkgeyBmb3VuZCA9IHRydWU7IGJyZWFrOyB9CiAgICAgIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMjAwMCk7CiAgICB9CiAgICBjb25zb2xlLmxvZyhgTXVsdGktYWdlbnQgbW9kZSB0cmlnZ2VyZWQ6ICR7Zm91bmR9IGluICR7KChEYXRlLm5vdygpLXdzMikvMTAwMCkudG9GaXhlZCgxKX1zYCk7CiAgICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDE1MDApOwogICAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDctMDMtbXVsdGlhZ2VudC5wbmciLCBmdWxsUGFnZTogZmFsc2UgfSk7CiAgICAKICB9IGVsc2UgewogICAgY29uc29sZS5sb2coIuKdjCBXaWRnZXQgYnV0dG9uIG5vdCBmb3VuZCIpOwogICAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDctbm93aWRnZXQucG5nIiwgZnVsbFBhZ2U6IHRydWUgfSk7CiAgfQp9KTsK");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v47-widget.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v48-deploy.php
Normal file
7
api/ambre-pw-v48-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNDggwrcgU0hPV0NBU0Ugwrcgd2lkZ2V0IG9uIGFsbC1pYS1odWIgKyA2IGFnZW50cyBtdWx0aSIsIGFzeW5jICh7IHBhZ2UgfSkgPT4gewogIHRlc3Quc2V0VGltZW91dCgxODAwMDApOwogIAogIGF3YWl0IHBhZ2UuZ290bygiL2FsbC1pYS1odWIuaHRtbD9jYj0iICsgRGF0ZS5ub3coKSk7CiAgYXdhaXQgcGFnZS53YWl0Rm9yTG9hZFN0YXRlKCJuZXR3b3JraWRsZSIpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMzAwMCk7CiAgCiAgY29uc3QgYnRuID0gYXdhaXQgcGFnZS5sb2NhdG9yKCIuYW13LWJ0biIpLmNvdW50KCk7CiAgaWYgKGJ0biA9PT0gMCkgeyBjb25zb2xlLmxvZygibm8gd2lkZ2V0Iik7IHJldHVybjsgfQogIAogIGF3YWl0IHBhZ2UubG9jYXRvcigiLmFtdy1idG4iKS5jbGljaygpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMTUwMCk7CiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDgtMDEtb3Blbi5wbmciIH0pOwogIAogIC8vIFNlbmQgbXVsdGktYWdlbnQgcmVxdWVzdCAtIGV4cGxvaXRzIFYyIGRpdmVyc2l0eQogIGF3YWl0IHBhZ2UubG9jYXRvcigiI2Ftd0lucHV0IikuZmlsbCgiZmFpcyBtb2kgdW5lIGFuYWx5c2UgY29tcGxldGUgZHUgbWFyY2jDqSBJQSBzb3V2ZXJhaW5lIDIwMjYgYXZlYyBhZ2VudHMgZXh0ZXJuZXMgZGl2ZXJzaWZpZXMiKTsKICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDMwMCk7CiAgYXdhaXQgcGFnZS5sb2NhdG9yKCIjYW13U2VuZCIpLmNsaWNrKCk7CiAgY29uc29sZS5sb2coIlNlbnQgbXVsdGktYWdlbnQgcmVxdWVzdCIpOwogIAogIC8vIFdhaXQgZm9yIG11bHRpLWFnZW50IGJhZGdlCiAgY29uc3Qgd3MgPSBEYXRlLm5vdygpOwogIHdoaWxlIChEYXRlLm5vdygpIC0gd3MgPCAxMjAwMDApIHsKICAgIGNvbnN0IG1hID0gYXdhaXQgcGFnZS5sb2NhdG9yKCIuYW13LW1zZy5hLm1hIikuY291bnQoKTsKICAgIGlmIChtYSA+IDApIGJyZWFrOwogICAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgyNTAwKTsKICB9CiAgY29uc3QgZWwgPSAoKERhdGUubm93KCktd3MpLzEwMDApLnRvRml4ZWQoMSk7CiAgY29uc29sZS5sb2coYE11bHRpLWFnZW50IGluICR7ZWx9c2ApOwogIAogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMTUwMCk7CiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDgtMDItbXVsdGkucG5nIiwgZnVsbFBhZ2U6IGZhbHNlIH0pOwogIAogIC8vIFNjcm9sbCB0byBzZWUgYWxsIHN5bnRoCiAgY29uc3QgcGFuZWwgPSBwYWdlLmxvY2F0b3IoIi5hbXctYm9keSIpOwogIGF3YWl0IHBhbmVsLmV2YWx1YXRlKGVsID0+IGVsLnNjcm9sbFRvcCA9IGVsLnNjcm9sbEhlaWdodCk7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCg1MDApOwogIGF3YWl0IHBhZ2Uuc2NyZWVuc2hvdCh7IHBhdGg6ICJvdXRwdXQvdjQ4LTAzLXN5bnRoLnBuZyIsIGZ1bGxQYWdlOiBmYWxzZSB9KTsKICAKICAvLyBHZXQgbGFzdCBtc2cgbWV0YQogIGNvbnN0IG1ldGEgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHsKICAgIGNvbnN0IGxhc3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCIuYW13LW1zZy5hLm1hIik7CiAgICBpZiAobGFzdC5sZW5ndGggPT09IDApIHJldHVybiB7dHVybnM6IDB9OwogICAgY29uc3QgbCA9IGxhc3RbbGFzdC5sZW5ndGgtMV07CiAgICByZXR1cm4gewogICAgICB0ZXh0OiBsLmlubmVyVGV4dC5zdWJzdHJpbmcoMCwgNDAwKSwKICAgICAgbWV0YTogbC5xdWVyeVNlbGVjdG9yKCIubWV0YSIpPy5pbm5lclRleHQgfHwgIiIsCiAgICAgIHR1cm5zOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYW13VHVybnMiKT8uaW5uZXJUZXh0IHx8ICI/IiwKICAgIH07CiAgfSk7CiAgY29uc29sZS5sb2coYFxuTWV0YTogJHttZXRhLm1ldGF9YCk7CiAgY29uc29sZS5sb2coYFR1cm5zIHRvdGFsOiAke21ldGEudHVybnN9YCk7CiAgY29uc29sZS5sb2coYFRleHQ6ICR7bWV0YS50ZXh0fWApOwp9KTsK");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v48-showcase.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v49-deploy.php
Normal file
7
api/ambre-pw-v49-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNDkgwrcgU2NhbiBwdWJsaWMgbGVha3Mgb24gLyBhbmQgL3dldmlhLmh0bWwiLCBhc3luYyAoeyBwYWdlIH0pID0+IHsKICB0ZXN0LnNldFRpbWVvdXQoNjAwMDApOwogIAogIC8vIFNjYW4gLwogIGF3YWl0IHBhZ2UuZ290bygiLz9jYj0iICsgRGF0ZS5ub3coKSk7CiAgYXdhaXQgcGFnZS53YWl0Rm9yTG9hZFN0YXRlKCJuZXR3b3JraWRsZSIpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMzAwMCk7CiAgCiAgY29uc3Qgcm9vdExlYWtzID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7CiAgICBjb25zdCBpZHMgPSBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tpZCo9Im9wdXMiXSwgW2lkKj0icGF0dGVybiJdLCBbaWQqPSJkb2NrIl0sIFtpZCo9InhsaW5rcyJdLCBbaWQqPSJ4bmF2Il0nKSk7CiAgICByZXR1cm4gaWRzLm1hcChlbCA9PiAoewogICAgICBpZDogZWwuaWQsCiAgICAgIHRhZzogZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpLAogICAgICB0ZXh0OiAoZWwuaW5uZXJUZXh0IHx8ICIiKS5zdWJzdHJpbmcoMCwgMjAwKSwKICAgICAgcG9zaXRpb246IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsKS5wb3NpdGlvbiwKICAgICAgdmlzaWJsZTogZWwub2Zmc2V0UGFyZW50ICE9PSBudWxsLAogICAgfSkpOwogIH0pOwogIGNvbnNvbGUubG9nKCJST09UIC8gbGVha3M6IiwgSlNPTi5zdHJpbmdpZnkocm9vdExlYWtzLCBudWxsLCAyKSk7CiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDktMDEtcm9vdC5wbmciLCBmdWxsUGFnZTogZmFsc2UgfSk7CiAgCiAgLy8gU2NhbiAvd2V2aWEuaHRtbAogIGF3YWl0IHBhZ2UuZ290bygiL3dldmlhLmh0bWw/Y2I9IiArIERhdGUubm93KCkpOwogIGF3YWl0IHBhZ2Uud2FpdEZvckxvYWRTdGF0ZSgibmV0d29ya2lkbGUiKTsKICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDMwMDApOwogIAogIGNvbnN0IHdldmlhTGVha3MgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHsKICAgIGNvbnN0IGlkcyA9IEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW2lkKj0ib3B1cyJdLCBbaWQqPSJwYXR0ZXJuIl0sIFtpZCo9ImRvY2siXSwgW2lkKj0ieGxpbmtzIl0sIFtpZCo9InhuYXYiXSwgW2lkKj0idWRvY2siXScpKTsKICAgIGNvbnN0IG91dCA9IGlkcy5tYXAoZWwgPT4gKHsKICAgICAgaWQ6IGVsLmlkLAogICAgICB0YWc6IGVsLnRhZ05hbWUudG9Mb3dlckNhc2UoKSwKICAgICAgdGV4dDogKGVsLmlubmVyVGV4dCB8fCAiIikuc3Vic3RyaW5nKDAsIDIwMCksCiAgICAgIHZpc2libGU6IGVsLm9mZnNldFBhcmVudCAhPT0gbnVsbCwKICAgIH0pKTsKICAgIC8vIEFsc28gbG9vayBmb3IgIkNsYXVkZSBQYXR0ZXJuIiB0ZXh0IGFueXdoZXJlIHZpc2libGUKICAgIGNvbnN0IGJvZHlUZXh0ID0gZG9jdW1lbnQuYm9keS5pbm5lclRleHQ7CiAgICBjb25zdCBoYXNfY2xhdWRlX3AgPSAvQ2xhdWRlXHMqUGF0dGVybi9pLnRlc3QoYm9keVRleHQpOwogICAgY29uc3QgaGFzX2FkbWluX2JhZGdlID0gL1xiQWRtaW5cYi9pLnRlc3QoYm9keVRleHQpICYmIC9cYkRyb2lkXGIvaS50ZXN0KGJvZHlUZXh0KTsKICAgIHJldHVybiB7IGVsZW1lbnRzOiBvdXQsIGhhc19jbGF1ZGVfcGF0dGVybl92aXNpYmxlOiBoYXNfY2xhdWRlX3AsIGhhc19hZG1pbl9kcm9pZDogaGFzX2FkbWluX2JhZGdlIH07CiAgfSk7CiAgY29uc29sZS5sb2coIlxuV0VWSUEgcHVibGljIGxlYWtzOiIsIEpTT04uc3RyaW5naWZ5KHdldmlhTGVha3MsIG51bGwsIDIpKTsKICBhd2FpdCBwYWdlLnNjcmVlbnNob3QoeyBwYXRoOiAib3V0cHV0L3Y0OS0wMi13ZXZpYS5wbmciLCBmdWxsUGFnZTogZmFsc2UgfSk7Cn0pOwo=");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v49-leaks.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v50-deploy.php
Normal file
7
api/ambre-pw-v50-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNTAgwrcgUFJPT0Ygc2hpZWxkIHJlbW92ZXMgbGVha3Mgb24gcHVibGljIHBhZ2VzIiwgYXN5bmMgKHsgcGFnZSB9KSA9PiB7CiAgdGVzdC5zZXRUaW1lb3V0KDYwMDAwKTsKICBjb25zdCBsb2dzID0gW107CiAgcGFnZS5vbigiY29uc29sZSIsIG0gPT4gbG9ncy5wdXNoKG0udGV4dCgpLnN1YnN0cmluZygwLCAxNTApKSk7CiAgCiAgLy8gVGVzdCAvCiAgYXdhaXQgcGFnZS5nb3RvKCIvP2NiPSIgKyBEYXRlLm5vdygpKTsKICBhd2FpdCBwYWdlLndhaXRGb3JMb2FkU3RhdGUoIm5ldHdvcmtpZGxlIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgzNTAwKTsKICAKICBjb25zdCByb290U3RhdGUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHsKICAgIGNvbnN0IGJvZHlUZXh0ID0gZG9jdW1lbnQuYm9keS5pbm5lclRleHQ7CiAgICByZXR1cm4gewogICAgICBzaXplOiBkb2N1bWVudC5ib2R5LmlubmVySFRNTC5sZW5ndGgsCiAgICAgIGhhc19jbGF1ZGVfcGF0dGVybjogL0NsYXVkZVxzKlBhdHRlcm4vaS50ZXN0KGJvZHlUZXh0KSwKICAgICAgaGFzX3d0cF9kb2NrX3Zpc2libGU6IEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW2lkKj0iZG9jayJdLCBbaWQqPSJ4bGlua3MiXSwgW2lkKj0ieG5hdiJdJykpLnNvbWUoZWwgPT4gZWwub2Zmc2V0UGFyZW50ICE9PSBudWxsICYmIC93dHB8ZHJvaWR8YWRtaW4vaS50ZXN0KGVsLmlubmVyVGV4dCkpLAogICAgICBoYXNfZGFzaGJvYXJkc19maXhlZDogQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcjb3B1cy1kYXNoYm9hcmQtbGluaywgW2lkKj0iZGFzaGJvYXJkLWVudHJ5Il0nKSkuc29tZShlbCA9PiBlbC5vZmZzZXRQYXJlbnQgIT09IG51bGwpLAogICAgICBzaGllbGRfbG9hZGVkOiAhIWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhbWJyZS1jb25maWRlbnRpYWwtc2hpZWxkJyksCiAgICAgIHZpc2libGVfZml4ZWRfaW50ZXJuYWw6IEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnYVtocmVmKj0id2V2YWwtdGVjaG5vbG9neS1wbGF0Zm9ybSJdLCBhW2hyZWYqPSJ3ZXZpYS1tYXN0ZXIiXSwgYVtocmVmKj0iYWxsLWlhLWh1YiJdJykpCiAgICAgICAgICAuZmlsdGVyKGEgPT4gewogICAgICAgICAgICB2YXIgcyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGEpOwogICAgICAgICAgICByZXR1cm4gcy5wb3NpdGlvbiA9PT0gJ2ZpeGVkJyAmJiBhLm9mZnNldFBhcmVudCAhPT0gbnVsbDsKICAgICAgICAgIH0pLmxlbmd0aCwKICAgIH07CiAgfSk7CiAgY29uc29sZS5sb2coIlJPT1QgLyBzdGF0ZToiLCBKU09OLnN0cmluZ2lmeShyb290U3RhdGUsIG51bGwsIDIpKTsKICBhd2FpdCBwYWdlLnNjcmVlbnNob3QoeyBwYXRoOiAib3V0cHV0L3Y1MC0wMS1yb290LnBuZyIsIGZ1bGxQYWdlOiBmYWxzZSB9KTsKICAKICAvLyBUZXN0IC93ZXZpYS5odG1sCiAgYXdhaXQgcGFnZS5nb3RvKCIvd2V2aWEuaHRtbD9jYj0iICsgRGF0ZS5ub3coKSk7CiAgYXdhaXQgcGFnZS53YWl0Rm9yTG9hZFN0YXRlKCJuZXR3b3JraWRsZSIpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMzUwMCk7CiAgCiAgY29uc3Qgd2V2aWFTdGF0ZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4gewogICAgY29uc3QgYm9keVRleHQgPSBkb2N1bWVudC5ib2R5LmlubmVyVGV4dDsKICAgIHJldHVybiB7CiAgICAgIGhhc19jbGF1ZGVfcGF0dGVybl90ZXh0OiAvQ2xhdWRlXHMqUGF0dGVybi9pLnRlc3QoYm9keVRleHQpLAogICAgICBvcHVzX3BhdHRlcm5fYmFkZ2VfdmlzaWJsZTogKGZ1bmN0aW9uKCl7IHZhciBlbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdvcHVzLXBhdHRlcm4tYmFkZ2UnKTsgcmV0dXJuIGVsID8gZWwub2Zmc2V0UGFyZW50ICE9PSBudWxsIDogZmFsc2U7IH0pKCksCiAgICAgIG9wdXNfcGF0dGVybl9zdHlsZV9wcmVzZW50OiAhIWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdvcHVzLXBhdHRlcm4tc3R5bGUnKSwKICAgICAgc2hpZWxkX2xvYWRlZDogISFkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYW1icmUtY29uZmlkZW50aWFsLXNoaWVsZCcpLAogICAgfTsKICB9KTsKICBjb25zb2xlLmxvZygiXG5XRVZJQSAvd2V2aWEuaHRtbCBzdGF0ZToiLCBKU09OLnN0cmluZ2lmeSh3ZXZpYVN0YXRlLCBudWxsLCAyKSk7CiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NTAtMDItd2V2aWEucG5nIiwgZnVsbFBhZ2U6IGZhbHNlIH0pOwogIAogIC8vIFNoaWVsZCBjb25zb2xlIGxvZ3MKICBjb25zdCBzaGllbGRMb2dzID0gbG9ncy5maWx0ZXIobCA9PiBsLmluY2x1ZGVzKCdzaGllbGQnKSk7CiAgY29uc29sZS5sb2coIlxuU2hpZWxkIGxvZ3M6Iiwgc2hpZWxkTG9ncyk7Cn0pOwo=");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v50-shield.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v51-deploy.php
Normal file
7
api/ambre-pw-v51-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNTEgwrcgUFJPT0YgZG9jayByZW1vdmVkIGZyb20gd2lkZ2V0ICsgaWZyYW1lIGNvbnRleHQiLCBhc3luYyAoeyBwYWdlIH0pID0+IHsKICB0ZXN0LnNldFRpbWVvdXQoNjAwMDApOwogIAogIC8vIERpcmVjdCBsb2FkIHdpZGdldAogIGF3YWl0IHBhZ2UuZ290bygiL3dldmlhLXdpZGdldC5odG1sP2NiPSIgKyBEYXRlLm5vdygpKTsKICBhd2FpdCBwYWdlLndhaXRGb3JMb2FkU3RhdGUoIm5ldHdvcmtpZGxlIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgzNTAwKTsKICAKICBjb25zdCBzdGF0ZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4gewogICAgY29uc3QgYm9keVRleHQgPSBkb2N1bWVudC5ib2R5LmlubmVyVGV4dDsKICAgIHJldHVybiB7CiAgICAgIGhhc19jbGF1ZGVfcGF0dGVybjogL0NsYXVkZVxzKlBhdHRlcm4vaS50ZXN0KGJvZHlUZXh0KSwKICAgICAgb3B1c19wYXR0ZXJuX2JhZGdlX3Zpc2libGU6IChmdW5jdGlvbigpeyB2YXIgZT1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnb3B1cy1wYXR0ZXJuLWJhZGdlJyk7IHJldHVybiBlP2Uub2Zmc2V0UGFyZW50IT09bnVsbDpmYWxzZTsgfSkoKSwKICAgICAgd3RwX3Vkb2NrX3Zpc2libGU6IChmdW5jdGlvbigpeyB2YXIgZT1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnd3RwLXVkb2NrJyk7IHJldHVybiBlP2Uub2Zmc2V0UGFyZW50IT09bnVsbDpmYWxzZTsgfSkoKSwKICAgICAgd3RwX3NpZGViYXJfdmlzaWJsZTogKGZ1bmN0aW9uKCl7IHZhciBlPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd3dHAtc2lkZWJhcicpOyByZXR1cm4gZT9lLm9mZnNldFBhcmVudCE9PW51bGw6ZmFsc2U7IH0pKCksCiAgICAgIGFueV9iYWRnZV93aXRoX2ludGVybmFsOiBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2FbaHJlZio9IndldmFsLXRlY2hub2xvZ3ktcGxhdGZvcm0iXSwgYVtocmVmKj0id2V2aWEtbWFzdGVyIl0sIGFbaHJlZio9ImFsbC1pYS1odWIiXScpKS5maWx0ZXIoYT0+YS5vZmZzZXRQYXJlbnQhPT1udWxsKS5sZW5ndGgsCiAgICAgIHNoaWVsZF9sb2FkZWQ6ICEhZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FtYnJlLWNvbmZpZGVudGlhbC1zaGllbGQnKSwKICAgIH07CiAgfSk7CiAgY29uc29sZS5sb2coIldJREdFVCBkaXJlY3Q6IiwgSlNPTi5zdHJpbmdpZnkoc3RhdGUsIG51bGwsIDIpKTsKICBhd2FpdCBwYWdlLnNjcmVlbnNob3QoeyBwYXRoOiAib3V0cHV0L3Y1MS0wMS13aWRnZXQtZGlyZWN0LnBuZyIsIGZ1bGxQYWdlOiBmYWxzZSB9KTsKICAKICAvLyBOb3cgdGVzdCBlbWJlZGRlZCBpbiBpZnJhbWUgKHNpbXVsYXRpbmcgcm9vdCAvIGNvbnRleHQpCiAgYXdhaXQgcGFnZS5nb3RvKCIvP2NiPSIgKyBEYXRlLm5vdygpKTsKICBhd2FpdCBwYWdlLndhaXRGb3JMb2FkU3RhdGUoIm5ldHdvcmtpZGxlIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCg0MDAwKTsKICAKICAvLyBGaW5kIGFueSBpZnJhbWUgd2l0aCB3ZXZpYS13aWRnZXQKICBjb25zdCBpZnJhbWVzID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7CiAgICByZXR1cm4gQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpZnJhbWUnKSkubWFwKGYgPT4gKHsKICAgICAgc3JjOiBmLnNyYywKICAgICAgdmlzaWJsZTogZi5vZmZzZXRQYXJlbnQgIT09IG51bGwsCiAgICAgIHNpemU6IGYuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksCiAgICB9KSk7CiAgfSk7CiAgY29uc29sZS5sb2coIlxuSWZyYW1lcyBvbiAvOiIsIEpTT04uc3RyaW5naWZ5KGlmcmFtZXMpKTsKICAKICAvLyBDaGVjayBpZiB3aWRnZXQgaWZyYW1lIGV4aXN0cyBhbmQgaW5zcGVjdCBpbnNpZGUKICBpZiAoaWZyYW1lcy5sZW5ndGggPiAwKSB7CiAgICBjb25zdCB3aWRnZXRGcmFtZSA9IHBhZ2UuZnJhbWVMb2NhdG9yKCdpZnJhbWVbc3JjKj0id2V2aWEtd2lkZ2V0Il0nKS5maXJzdCgpOwogICAgdHJ5IHsKICAgICAgY29uc3QgZnJhbWVTdGF0ZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4gewogICAgICAgIGNvbnN0IGlmcnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpZnJhbWUnKTsKICAgICAgICBmb3IgKGNvbnN0IGlmciBvZiBpZnJzKSB7CiAgICAgICAgICBpZiAoaWZyLnNyYyAmJiBpZnIuc3JjLmluY2x1ZGVzKCd3ZXZpYS13aWRnZXQnKSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgIGNvbnN0IGRvYyA9IGlmci5jb250ZW50RG9jdW1lbnQ7CiAgICAgICAgICAgICAgaWYgKCFkb2MpIGNvbnRpbnVlOwogICAgICAgICAgICAgIGNvbnN0IGJ0ID0gZG9jLmJvZHkgPyBkb2MuYm9keS5pbm5lclRleHQgOiAiIjsKICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgc3JjOiBpZnIuc3JjLAogICAgICAgICAgICAgICAgaGFzX2NsYXVkZV9wYXR0ZXJuOiAvQ2xhdWRlXHMqUGF0dGVybi9pLnRlc3QoYnQpLAogICAgICAgICAgICAgICAgaGFzX3d0cDogL1xiV1RQXGIvaS50ZXN0KGJ0KSwKICAgICAgICAgICAgICAgIGhhc19hZG1pbl9kcm9pZDogL1xiQWRtaW5cYi9pLnRlc3QoYnQpICYmIC9cYkRyb2lkXGIvaS50ZXN0KGJ0KSwKICAgICAgICAgICAgICAgIHRleHRfc2l6ZTogYnQubGVuZ3RoLAogICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0gY2F0Y2goZSl7IHJldHVybiB7ZXJyb3I6ICJjcm9zcy1vcmlnaW4iLCBtc2c6IGUubWVzc2FnZX07IH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICJubyB3aWRnZXQgaWZyYW1lIjsKICAgICAgfSk7CiAgICAgIGNvbnNvbGUubG9nKCJXaWRnZXQgaWZyYW1lIHN0YXRlOiIsIEpTT04uc3RyaW5naWZ5KGZyYW1lU3RhdGUpKTsKICAgIH0gY2F0Y2goZSkgeyBjb25zb2xlLmxvZygiZnJhbWUgaW5zcGVjdCBlcnI6IiwgZS5tZXNzYWdlKTsgfQogIH0KICAKICBhd2FpdCBwYWdlLnNjcmVlbnNob3QoeyBwYXRoOiAib3V0cHV0L3Y1MS0wMi1yb290LXdpdGgtaWZyYW1lLnBuZyIsIGZ1bGxQYWdlOiBmYWxzZSB9KTsKICAKICAvLyBGb3JjZSBjbGljayB3aWRnZXQgYnV0dG9uIHRvIG9wZW4gcGFuZWwKICBjb25zdCBidG4gPSBhd2FpdCBwYWdlLmxvY2F0b3IoJ2J1dHRvbjpoYXMtdGV4dCgiT3V2cmlyIiksIGJ1dHRvbjpoYXMtdGV4dCgiQ2hhdCIpLCBbY2xhc3MqPSJjaGF0Il1bY2xhc3MqPSJidG4iXSwgW2NsYXNzKj0id2lkZ2V0Il1bY2xhc3MqPSJidG4iXScpLmZpcnN0KCk7CiAgaWYgKGF3YWl0IGJ0bi5jb3VudCgpID4gMCkgewogICAgdHJ5IHsKICAgICAgYXdhaXQgYnRuLmNsaWNrKHtmb3JjZTogdHJ1ZSwgdGltZW91dDogMzAwMH0pOwogICAgICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDIwMDApOwogICAgICBhd2FpdCBwYWdlLnNjcmVlbnNob3QoeyBwYXRoOiAib3V0cHV0L3Y1MS0wMy1wYW5lbC1vcGVuLnBuZyIsIGZ1bGxQYWdlOiBmYWxzZSB9KTsKICAgIH0gY2F0Y2goZSkgeyBjb25zb2xlLmxvZygiYnRuIGNsaWNrIGVycjoiLCBlLm1lc3NhZ2UpOyB9CiAgfQp9KTsK");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v51-widget.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v52-deploy.php
Normal file
7
api/ambre-pw-v52-deploy.php
Normal file
File diff suppressed because one or more lines are too long
7
api/ambre-pw-v53-deploy.php
Normal file
7
api/ambre-pw-v53-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNTMgwrcgRmluYWwgcHJvb2Ygd2lkZ2V0IGNsZWFuIChubyBDbGF1ZGUgUGF0dGVybiBwYW5lbCkiLCBhc3luYyAoeyBwYWdlIH0pID0+IHsKICB0ZXN0LnNldFRpbWVvdXQoNjAwMDApOwogIAogIGF3YWl0IHBhZ2UuZ290bygiL3dldmlhLXdpZGdldC5odG1sP2NiPSIgKyBEYXRlLm5vdygpKTsKICBhd2FpdCBwYWdlLndhaXRGb3JMb2FkU3RhdGUoIm5ldHdvcmtpZGxlIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCg0MDAwKTsKICAKICBjb25zdCBzdGF0ZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4gewogICAgY29uc3QgYm9keVRleHQgPSBkb2N1bWVudC5ib2R5LmlubmVyVGV4dDsKICAgIHJldHVybiB7CiAgICAgIHZpc2libGVfY2xhdWRlX3BhdHRlcm5fdGV4dDogL0NsYXVkZVxzKlBhdHRlcm4vaS50ZXN0KGJvZHlUZXh0KSwKICAgICAgb3B1c19wYXR0ZXJuX2JhZGdlOiAhIWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdvcHVzLXBhdHRlcm4tYmFkZ2UnKSAmJiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnb3B1cy1wYXR0ZXJuLWJhZGdlJykub2Zmc2V0UGFyZW50ICE9PSBudWxsLAogICAgICBvcHVzX3BhdHRlcm5fbW9kYWw6ICEhZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ29wdXMtcGF0dGVybi1tb2RhbCcpICYmIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdvcHVzLXBhdHRlcm4tbW9kYWwnKS5vZmZzZXRQYXJlbnQgIT09IG51bGwsCiAgICAgIG9wdXNfcGF0dGVybl9ib3g6ICEhZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ29wdXMtcGF0dGVybi1ib3gnKSAmJiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnb3B1cy1wYXR0ZXJuLWJveCcpLm9mZnNldFBhcmVudCAhPT0gbnVsbCwKICAgICAgc2V2ZW5fcGhhc2VzX3Zpc2libGU6IC83IHBoYXNlcyBSRUFML2kudGVzdChib2R5VGV4dCksCiAgICAgIHNzZV9saXZlX3Zpc2libGU6IC9TU0UgbGl2ZS9pLnRlc3QoYm9keVRleHQpLAogICAgICBsYW5jZXJfdmlzaWJsZTogL0xhbmNlciBcKFNTRS9pLnRlc3QoYm9keVRleHQpLAogICAgICBzaGllbGRfbG9hZGVkOiAhIWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhbWJyZS1jb25maWRlbnRpYWwtc2hpZWxkJyksCiAgICAgIG9wdXNQYXR0ZXJuT3Blbl9uZXV0cmFsaXplZDogKHR5cGVvZiB3aW5kb3cuX19vcHVzUGF0dGVybk9wZW4gPT09ICdmdW5jdGlvbicpICYmIHdpbmRvdy5fX29wdXNQYXR0ZXJuT3Blbi50b1N0cmluZygpLmxlbmd0aCA8IDMwLAogICAgfTsKICB9KTsKICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShzdGF0ZSwgbnVsbCwgMikpOwogIAogIGF3YWl0IHBhZ2Uuc2NyZWVuc2hvdCh7IHBhdGg6ICJvdXRwdXQvdjUzLWZpbmFsLXdpZGdldC5wbmciLCBmdWxsUGFnZTogZmFsc2UgfSk7CiAgCiAgLy8gVHJ5IGNhbGwgX19vcHVzUGF0dGVybk9wZW4gdG8gc2VlIGlmIG5ldXRyYWxpemVkCiAgY29uc3Qgb3BlblJlc3VsdCA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4gewogICAgdHJ5IHsKICAgICAgd2luZG93Ll9fb3B1c1BhdHRlcm5PcGVuKCk7CiAgICAgIGNvbnN0IG1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ29wdXMtcGF0dGVybi1tb2RhbCcpOwogICAgICByZXR1cm4gbW9kYWwgPyAobW9kYWwub2Zmc2V0UGFyZW50ICE9PSBudWxsID8gIk9QRU5FRF9WSVNJQkxFIiA6ICJISURERU4iKSA6ICJOT19NT0RBTCI7CiAgICB9IGNhdGNoKGUpIHsgcmV0dXJuICJFUlJPUjogIiArIGUubWVzc2FnZTsgfQogIH0pOwogIGNvbnNvbGUubG9nKCJBZnRlciBfX29wdXNQYXR0ZXJuT3BlbiBjYWxsOiIsIG9wZW5SZXN1bHQpOwogIGF3YWl0IHBhZ2Uuc2NyZWVuc2hvdCh7IHBhdGg6ICJvdXRwdXQvdjUzLWFmdGVyLW9wZW4tYXR0ZW1wdC5wbmciIH0pOwp9KTsK");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v53-final.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v54.php
Normal file
7
api/ambre-pw-v54.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNTQgwrcgTWVybWFpZCBTVkcgcmVuZGVyIGluIHBoYXNlIDUvNSIsIGFzeW5jICh7IHBhZ2UgfSkgPT4gewogIHRlc3Quc2V0VGltZW91dCg5MDAwMCk7CiAgY29uc3QgbG9ncyA9IFtdOwogIHBhZ2Uub24oImNvbnNvbGUiLCBtID0+IGxvZ3MucHVzaChtLnRleHQoKS5zdWJzdHJpbmcoMCwgMjAwKSkpOwogIAogIGF3YWl0IHBhZ2UuZ290bygiL3dldmlhLmh0bWw/Y2I9IiArIERhdGUubm93KCkpOwogIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4geyB0cnl7c2Vzc2lvblN0b3JhZ2UuY2xlYXIoKTt9Y2F0Y2goZSl7fSB9KTsKICBhd2FpdCBwYWdlLndhaXRGb3JMb2FkU3RhdGUoIm5ldHdvcmtpZGxlIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgzNTAwKTsKICAKICBjb25zdCBpbnB1dCA9IHBhZ2UubG9jYXRvcigiI21zZ0lucHV0Iik7CiAgYXdhaXQgaW5wdXQuY2xpY2soe2ZvcmNlOnRydWV9KTsKICBhd2FpdCBpbnB1dC5maWxsKCJHZW5lcmUgdW4gc2NoZW1hIG1lcm1haWQgcG91cjogd2V2aWEiKTsKICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDQwMCk7CiAgYXdhaXQgaW5wdXQucHJlc3MoIkVudGVyIik7CiAgY29uc29sZS5sb2coIlNlbnQgbWVybWFpZCByZXF1ZXN0Iik7CiAgCiAgLy8gV2FpdCBmb3IgY29tcGxldGlvbgogIGNvbnN0IHdzID0gRGF0ZS5ub3coKTsKICBsZXQgcmVuZGVyZWQgPSBmYWxzZTsKICB3aGlsZSAoRGF0ZS5ub3coKSAtIHdzIDwgNjAwMDApIHsKICAgIGNvbnN0IHN0YXRlID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7CiAgICAgIC8vIExvb2sgZm9yIGEgcmVuZGVyZWQgU1ZHIGluIGFueSBhbWJyZS1waGFzZS1yZXN1bHQgb3IgcmVzdWx0IGJsb2NrCiAgICAgIGNvbnN0IHN2Z3MgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuYW1icmUtcGhhc2UtcmVzdWx0IHN2ZywgLnBoYXNlLWNvbnRlbnQgc3ZnLCBbaWRePSJ3di1tZXJtYWlkLSJdIHN2ZycpOwogICAgICBjb25zdCBoYXNTdmcgPSBzdmdzLmxlbmd0aCA+IDA7CiAgICAgIC8vIENoZWNrIFdFVklBLXBhdHRlcm4gdnMgQ2xhdWRlLXBhdHRlcm4gaW4gcmVuZGVyZWQgSFRNTAogICAgICBjb25zdCBodG1sID0gZG9jdW1lbnQuYm9keS5pbm5lckhUTUw7CiAgICAgIHJldHVybiB7CiAgICAgICAgcGhhc2VfY291bnQ6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5hbWJyZS1waGFzZScpLmxlbmd0aCwKICAgICAgICBzdmdfY291bnQ6IHN2Z3MubGVuZ3RoLAogICAgICAgIGhhc193ZXZpYV9wYXR0ZXJuOiAvV0VWSUFbLSBdP3BhdHRlcm4vaS50ZXN0KGh0bWwpLAogICAgICAgIGhhc19jbGF1ZGVfcGF0dGVybjogL0NsYXVkZVstIF0/cGF0dGVybi9pLnRlc3QoaHRtbCksCiAgICAgICAgYnVzeTogISF3aW5kb3cuYnVzeSB8fCAhIWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZW5kQnRuJyk/LmRpc2FibGVkLAogICAgICB9OwogICAgfSk7CiAgICBpZiAoc3RhdGUuc3ZnX2NvdW50ID4gMCAmJiAhc3RhdGUuYnVzeSkgeyByZW5kZXJlZCA9IHRydWU7IGNvbnNvbGUubG9nKGBTVkcgcmVuZGVyZWQhIHN0YXRlPSR7SlNPTi5zdHJpbmdpZnkoc3RhdGUpfWApOyBicmVhazsgfQogICAgaWYgKCFzdGF0ZS5idXN5ICYmIHN0YXRlLnBoYXNlX2NvdW50ID49IDUpIHsKICAgICAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgyMDAwKTsKICAgICAgY29uc3QgczIgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5hbWJyZS1waGFzZS1yZXN1bHQgc3ZnLCAucGhhc2UtY29udGVudCBzdmcsIFtpZF49Ind2LW1lcm1haWQtIl0gc3ZnJykubGVuZ3RoKTsKICAgICAgY29uc29sZS5sb2coYEFmdGVyIHdhaXQ6ICR7czJ9IFNWR3MsIGJ1c3k9JHtzdGF0ZS5idXN5fWApOwogICAgICBpZiAoczIgPiAwKSByZW5kZXJlZCA9IHRydWU7CiAgICAgIGJyZWFrOwogICAgfQogICAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgyNTAwKTsKICB9CiAgCiAgY29uc3QgZWxhcHNlZCA9ICgoRGF0ZS5ub3coKS13cykvMTAwMCkudG9GaXhlZCgxKTsKICBjb25zdCBmaW5hbFN0YXRlID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7CiAgICBjb25zdCBodG1sID0gZG9jdW1lbnQuYm9keS5pbm5lckhUTUw7CiAgICBjb25zdCBzdmdzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmFtYnJlLXBoYXNlLXJlc3VsdCBzdmcsIC5waGFzZS1jb250ZW50IHN2ZywgW2lkXj0id3YtbWVybWFpZC0iXSBzdmcnKTsKICAgIHJldHVybiB7CiAgICAgIHN2Z192aXNpYmxlOiBBcnJheS5mcm9tKHN2Z3MpLmZpbHRlcihzID0+IHMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGggPiAxMCkubGVuZ3RoLAogICAgICBzdmdfaHRtbF9sZW46IHN2Z3MubGVuZ3RoID4gMCA/IHN2Z3NbMF0ub3V0ZXJIVE1MLmxlbmd0aCA6IDAsCiAgICAgIGhhc193ZXZpYV9wYXR0ZXJuOiAvV0VWSUFbLSBdP3BhdHRlcm4vaS50ZXN0KGh0bWwpLAogICAgICBoYXNfY2xhdWRlX3BhdHRlcm46IC9DbGF1ZGVbLSBdP3BhdHRlcm4vaS50ZXN0KGh0bWwpLAogICAgICBoYXNfbWVybWFpZF9jb2RlX3JhdzogL3NlcXVlbmNlRGlhZ3JhbXxmbG93Y2hhcnR8Z3JhcGhccytbQS1aXS9pLnRlc3QoaHRtbCksCiAgICB9OwogIH0pOwogIGNvbnNvbGUubG9nKGBcbuKVkOKVkOKVkCBGSU5BTCBpbiAke2VsYXBzZWR9cyDCtyByZW5kZXJlZD0ke3JlbmRlcmVkfSDilZDilZDilZBgKTsKICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShmaW5hbFN0YXRlLCBudWxsLCAyKSk7CiAgCiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NTQtbWVybWFpZC1maW5hbC5wbmciLCBmdWxsUGFnZTogdHJ1ZSB9KTsKICAKICAvLyBBbHNvIGNoZWNrIHJlbGV2YW50IGxvZ3MKICBsb2dzLmZpbHRlcihsID0+IC9tZXJtYWlkfE1FUk1BSUR8cmVuZGVyfFY1L2kudGVzdChsKSkuZm9yRWFjaChsID0+IGNvbnNvbGUubG9nKCJMT0c6IiwgbCkpOwp9KTsK");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v54-mermaid.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v55.php
Normal file
7
api/ambre-pw-v55.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNTUgwrcgc2Nyb2xsIHRvIHNlZSBtZXJtYWlkIFNWRyIsIGFzeW5jICh7IHBhZ2UgfSkgPT4gewogIHRlc3Quc2V0VGltZW91dCg5MDAwMCk7CiAgCiAgYXdhaXQgcGFnZS5nb3RvKCIvd2V2aWEuaHRtbD9jYj0iICsgRGF0ZS5ub3coKSk7CiAgYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7IHRyeXtzZXNzaW9uU3RvcmFnZS5jbGVhcigpO31jYXRjaChlKXt9IH0pOwogIGF3YWl0IHBhZ2Uud2FpdEZvckxvYWRTdGF0ZSgibmV0d29ya2lkbGUiKTsKICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDM1MDApOwogIAogIGNvbnN0IGlucHV0ID0gcGFnZS5sb2NhdG9yKCIjbXNnSW5wdXQiKTsKICBhd2FpdCBpbnB1dC5jbGljayh7Zm9yY2U6dHJ1ZX0pOwogIGF3YWl0IGlucHV0LmZpbGwoIkdlbmVyZSB1biBzY2hlbWEgbWVybWFpZCBwb3VyOiBhcmNoaXRlY3R1cmUgV0VWSUEgc291dmVyYWluZSIpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoNDAwKTsKICBhd2FpdCBpbnB1dC5wcmVzcygiRW50ZXIiKTsKICAKICAvLyBXYWl0IGZvciBjb21wbGV0aW9uCiAgY29uc3Qgd3MgPSBEYXRlLm5vdygpOwogIHdoaWxlIChEYXRlLm5vdygpIC0gd3MgPCA2MDAwMCkgewogICAgY29uc3QgYnVzeSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4gd2luZG93LmJ1c3kgfHwgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NlbmRCdG4nKT8uZGlzYWJsZWQpOwogICAgY29uc3Qgc3ZncyA9IGF3YWl0IHBhZ2UubG9jYXRvcignW2lkXj0id3YtbWVybWFpZC0iXSBzdmcsIC5waGFzZS1jb250ZW50IHN2ZycpLmNvdW50KCk7CiAgICBpZiAoIWJ1c3kgJiYgc3ZncyA+IDApIGJyZWFrOwogICAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgyMDAwKTsKICB9CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgyMDAwKTsKICAKICAvLyBTY3JvbGwgdG8gdGhlIFNWRwogIGNvbnN0IHNjcm9sbGVkID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7CiAgICBjb25zdCBzdmcgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbaWRePSJ3di1tZXJtYWlkLSJdIHN2ZywgLnBoYXNlLWNvbnRlbnQgc3ZnJyk7CiAgICBpZiAoc3ZnKSB7CiAgICAgIHN2Zy5zY3JvbGxJbnRvVmlldyh7YmxvY2s6J2NlbnRlcicsIGJlaGF2aW9yOidpbnN0YW50J30pOwogICAgICByZXR1cm4gewogICAgICAgIHN2Z192aXNpYmxlOiBzdmcuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGggPiAxMCwKICAgICAgICBzdmdfd2lkdGg6IHN2Zy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCwKICAgICAgICBzdmdfaGVpZ2h0OiBzdmcuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0LAogICAgICAgIHN2Z19odG1sX3NpemU6IHN2Zy5vdXRlckhUTUwubGVuZ3RoLAogICAgICAgIHdyYXBwZXJfaWQ6IHN2Zy5wYXJlbnRFbGVtZW50Py5pZCwKICAgICAgfTsKICAgIH0KICAgIHJldHVybiBudWxsOwogIH0pOwogIGNvbnNvbGUubG9nKCJTVkcgcmVuZGVyZWQ6IiwgSlNPTi5zdHJpbmdpZnkoc2Nyb2xsZWQsIG51bGwsIDIpKTsKICAKICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDUwMCk7CiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NTUtc2Nyb2xsZWQucG5nIiwgZnVsbFBhZ2U6IGZhbHNlIH0pOwogIGF3YWl0IHBhZ2Uuc2NyZWVuc2hvdCh7IHBhdGg6ICJvdXRwdXQvdjU1LWZ1bGwucG5nIiwgZnVsbFBhZ2U6IHRydWUgfSk7Cn0pOwo=");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v55-scroll.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
55
api/ambre-rename-claude.php
Normal file
55
api/ambre-rename-claude.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/wevia.html";
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
$changes = [];
|
||||
|
||||
// Fix 1: rename "WEVIA Claude-pattern" in header
|
||||
$c_new = preg_replace("/<strong>WEVIA Claude[- ]?pattern<\/strong>/i", "<strong>WEVIA-pattern</strong>", $c);
|
||||
$c_new = preg_replace("/WEVIA Claude[- ]?pattern/", "WEVIA-pattern", $c_new);
|
||||
if ($c_new !== $c) {
|
||||
$changes[] = "renamed_WEVIA_Claude_pattern";
|
||||
$c = $c_new;
|
||||
}
|
||||
|
||||
// Fix 2: Remove any "Claude" mentions in phase labels
|
||||
$c_new = str_replace("Claude Pattern", "WEVIA-Pattern", $c);
|
||||
$c_new = str_replace("claude-pattern", "wevia-pattern", $c_new);
|
||||
$c_new = str_replace("Claude-pattern", "WEVIA-pattern", $c_new);
|
||||
if ($c_new !== $c) {
|
||||
$changes[] = "renamed_claude_pattern_generic";
|
||||
$c = $c_new;
|
||||
}
|
||||
|
||||
// Fix 3: Remove mentions of "Claude" alone that are confidential
|
||||
// But KEEP internal vars like _claude_xxx since they're code
|
||||
// Target ONLY user-facing strings (between quotes or HTML text)
|
||||
$user_facing_replacements = [
|
||||
"'Claude'" => "'WEVIA'",
|
||||
"\"Claude\"" => "\"WEVIA\"",
|
||||
">Claude<" => ">WEVIA<",
|
||||
"'Claude pattern'" => "'WEVIA pattern'",
|
||||
"\"Claude pattern\"" => "\"WEVIA pattern\"",
|
||||
];
|
||||
foreach ($user_facing_replacements as $k => $v) {
|
||||
if (strpos($c, $k) !== false) {
|
||||
$c = str_replace($k, $v, $c);
|
||||
$changes[] = "replaced_" . md5($k);
|
||||
}
|
||||
}
|
||||
|
||||
// Verify no more "Claude-pattern" in UI
|
||||
$out_count = substr_count($c, "Claude-pattern") + substr_count($c, "Claude pattern") + substr_count($c, "Claude Pattern");
|
||||
|
||||
$backup = "/opt/wevads/vault/wevia.html.GOLD-" . date("Ymd-His") . "-wave263-rename";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $c);
|
||||
|
||||
echo json_encode([
|
||||
"delta" => strlen($c) - $orig,
|
||||
"wrote" => $wrote,
|
||||
"backup" => basename($backup),
|
||||
"changes" => $changes,
|
||||
"remaining_claude_pattern_count" => $out_count,
|
||||
]);
|
||||
3
api/ambre-sc-read.php
Normal file
3
api/ambre-sc-read.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
echo @file_get_contents("/var/www/html/api/ambre-session-chat.php");
|
||||
43
api/ambre-scan-claude.php
Normal file
43
api/ambre-scan-claude.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
// Files that render "Claude" or "Claude-pattern" badge VISIBLE on public wevia.html
|
||||
$w = @file_get_contents("/var/www/html/wevia.html");
|
||||
$out["wevia_html"] = [
|
||||
"size" => strlen($w),
|
||||
"claude_text_count" => substr_count($w, "Claude"),
|
||||
"claude_pattern_count" => preg_match_all("/Claude[\s\-]?pattern/i", $w),
|
||||
"WEVIA_Claude_pattern" => substr_count($w, "WEVIA Claude-pattern"),
|
||||
"Claude_pattern_span" => preg_match_all("/<span[^>]*>Claude[\s\-]?[Pp]attern/i", $w),
|
||||
];
|
||||
|
||||
// Find the exact rendering in wevia.html
|
||||
$pos = strpos($w, "Claude-pattern");
|
||||
if ($pos === false) $pos = strpos($w, "Claude pattern");
|
||||
if ($pos === false) $pos = strpos($w, "WEVIA Claude");
|
||||
if ($pos !== false) $out["wevia_context"] = substr($w, max(0, $pos - 200), 500);
|
||||
|
||||
// Mermaid generator - check output
|
||||
$mp = @file_get_contents("/var/www/html/api/ambre-tool-mermaid.php");
|
||||
$out["mermaid_tool"] = [
|
||||
"size" => strlen($mp ?? ""),
|
||||
"exists" => file_exists("/var/www/html/api/ambre-tool-mermaid.php"),
|
||||
];
|
||||
|
||||
// Find V5-claude-pattern source
|
||||
$out["claude_pattern_sources"] = trim(@shell_exec("grep -lE 'claude[- ]?pattern|Claude[- ]?[Pp]attern' /var/www/html/wevia.html /var/www/html/*.html /var/www/html/api/*.php 2>/dev/null | head -10"));
|
||||
|
||||
// Check V5-CLAUDE-PATTERN block in wevia.html
|
||||
if (preg_match("/\/\/ === AMBRE-V5-CLAUDE-PATTERN.{0,10000}\/\/ === END AMBRE-V5-CLAUDE-PATTERN/s", $w, $m)) {
|
||||
$out["v5_block_size"] = strlen($m[0]);
|
||||
// Extract the rendered badges
|
||||
if (preg_match_all('/["\']WEVIA[^"\']*Claude[^"\']*pattern[^"\']*["\']/', $m[0], $badges)) {
|
||||
$out["v5_badges"] = $badges[0];
|
||||
}
|
||||
if (preg_match_all('/["\']WEVIA[- ]?pattern["\']/i', $m[0], $badges2)) {
|
||||
$out["v5_badges_alt"] = $badges2[0];
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
46
api/ambre-scan-w259.php
Normal file
46
api/ambre-scan-w259.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
chdir("/var/www/html");
|
||||
|
||||
$out["recent_tags"] = array_filter(array_map("trim", explode("\n", @shell_exec("git tag -l 'wave-*' --sort=-creatordate 2>&1 | head -8"))));
|
||||
$out["recent_commits_30m"] = array_filter(array_map("trim", explode("\n", @shell_exec("git log --since='30 minutes ago' --oneline 2>&1 | head -10"))));
|
||||
|
||||
// Internal chats candidates - what pages have chatbots?
|
||||
$chat_pages = [];
|
||||
foreach (["wevia.html", "wevia-master.html", "all-ia-hub.html", "wevia-orchestrator.html", "index.html", "director-chat.html", "l99-brain.html", "agents-enterprise.html", "paperclip.html", "director-center.html"] as $p) {
|
||||
$f = "/var/www/html/$p";
|
||||
if (file_exists($f)) {
|
||||
$c = @file_get_contents($f);
|
||||
$chat_pages[$p] = [
|
||||
"size" => strlen($c),
|
||||
"has_chat_api" => strpos($c, "session-chat") !== false || strpos($c, "wevia-master-api") !== false || strpos($c, "wevia-autonomous") !== false || strpos($c, "chat-api") !== false,
|
||||
"has_sessionstorage" => strpos($c, "sessionStorage") !== false,
|
||||
"has_internal_memory" => strpos($c, "internal-memory") !== false,
|
||||
];
|
||||
}
|
||||
}
|
||||
$out["chat_pages"] = $chat_pages;
|
||||
|
||||
// Cloudflare workers/rules check
|
||||
$cf = @file_get_contents("/etc/weval/secrets.env");
|
||||
$out["cf_token_present"] = (bool)preg_match("/CF_API_TOKEN=.{20,}/", $cf ?? "");
|
||||
$out["cf_token_len"] = 0;
|
||||
if (preg_match("/CF_API_TOKEN=([^\n\"]+)/", $cf ?? "", $m)) $out["cf_token_len"] = strlen($m[1]);
|
||||
|
||||
// Check CF cache status on chatbot endpoints (are they cached wrongly?)
|
||||
$endpoints = ["/api/ambre-session-chat.php", "/api/wevia-autonomous.php", "/api/ambre-multiagent-parallel.php"];
|
||||
$out["cf_cache_status"] = [];
|
||||
foreach ($endpoints as $ep) {
|
||||
$h = @get_headers("https://weval-consulting.com$ep?cb=" . time(), 1);
|
||||
$out["cf_cache_status"][$ep] = $h["cf-cache-status"] ?? $h["CF-Cache-Status"] ?? "none";
|
||||
}
|
||||
|
||||
// Check cross-chat learning possibility
|
||||
$out["internal_memory_dir_exists"] = is_dir("/opt/wevads/internal-memory");
|
||||
$out["internal_memory_chats"] = count(glob("/opt/wevads/internal-memory/*.jsonl") ?: []);
|
||||
|
||||
// Load
|
||||
$out["load"] = trim(@shell_exec("uptime"));
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
68
api/ambre-scan-w260.php
Normal file
68
api/ambre-scan-w260.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
chdir("/var/www/html");
|
||||
$out["recent_tags"] = array_filter(array_map("trim", explode("\n", @shell_exec("git tag -l 'wave-*' --sort=-creatordate 2>&1 | head -10"))));
|
||||
$out["recent_commits"] = array_filter(array_map("trim", explode("\n", @shell_exec("git log --since='30 minutes ago' --oneline 2>&1 | head -12"))));
|
||||
|
||||
// External AIs/agents available on this server (L99, Director, Blade, Arena, AlliaHub, Paperclip, DeerFlow)
|
||||
$ext_agents = [
|
||||
"L99" => "http://127.0.0.1:5890", // S95 arsenal
|
||||
"Paperclip" => "http://127.0.0.1:3201",
|
||||
"DeerFlow" => "http://127.0.0.1:3002",
|
||||
"MiroFish" => "http://127.0.0.1:3050",
|
||||
"TwentyCRM" => "http://127.0.0.1:3000",
|
||||
"n8n" => "http://127.0.0.1:5678",
|
||||
"Ollama" => "http://127.0.0.1:11434",
|
||||
"Qdrant" => "http://127.0.0.1:6333",
|
||||
"Cascade" => "http://127.0.0.1:4000",
|
||||
"Mattermost" => "http://127.0.0.1:8065",
|
||||
];
|
||||
$out["external_agents"] = [];
|
||||
foreach ($ext_agents as $n => $url) {
|
||||
$t0 = microtime(true);
|
||||
$r = @file_get_contents($url, false, stream_context_create(["http"=>["timeout"=>2,"ignore_errors"=>true]]));
|
||||
$out["external_agents"][$n] = [
|
||||
"url" => $url,
|
||||
"up" => (bool)$r,
|
||||
"ms" => round((microtime(true)-$t0)*1000),
|
||||
];
|
||||
}
|
||||
|
||||
// Check CF Transform Rules possibility (needs CF token working)
|
||||
$cf_token = null;
|
||||
if (file_exists("/etc/weval/secrets.env")) {
|
||||
$sc = @file_get_contents("/etc/weval/secrets.env");
|
||||
if (preg_match("/CF_API_TOKEN=([^\n\"]+)/", $sc, $m)) $cf_token = trim($m[1]);
|
||||
}
|
||||
$out["cf_token_len"] = $cf_token ? strlen($cf_token) : 0;
|
||||
|
||||
// Test CF token
|
||||
if ($cf_token) {
|
||||
$ctx = stream_context_create(["http"=>["method"=>"GET","header"=>"Authorization: Bearer $cf_token\r\n","timeout"=>5,"ignore_errors"=>true]]);
|
||||
$verify = @file_get_contents("https://api.cloudflare.com/client/v4/user/tokens/verify", false, $ctx);
|
||||
$v = @json_decode($verify, true);
|
||||
$out["cf_token_status"] = $v["success"] ?? false;
|
||||
$out["cf_token_msg"] = substr($verify ?? "none", 0, 200);
|
||||
}
|
||||
|
||||
// Registered chatbots needing memory wire
|
||||
$out["pages_with_widget"] = [];
|
||||
foreach (["wevia.html", "wevia-master.html", "all-ia-hub.html", "wevia-orchestrator.html", "director-chat.html", "l99-brain.html", "director-center.html", "paperclip.html", "agents-enterprise.html", "wevia-multiagent-dashboard.html"] as $p) {
|
||||
$f = "/var/www/html/$p";
|
||||
if (file_exists($f)) {
|
||||
$c = @file_get_contents($f);
|
||||
$out["pages_with_widget"][$p] = [
|
||||
"size" => strlen($c),
|
||||
"has_universal_widget" => strpos($c, "ambre-universal-chat.js") !== false,
|
||||
"has_chat_api" => strpos($c, "chat-api") !== false || strpos($c, "session-chat") !== false,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Internal memory state now
|
||||
$out["internal_memory_files"] = array_map("basename", glob("/opt/wevads/internal-memory/*.jsonl") ?: []);
|
||||
$out["internal_memory_count"] = count($out["internal_memory_files"]);
|
||||
|
||||
$out["load"] = trim(@shell_exec("uptime"));
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
51
api/ambre-shield-v2.php
Normal file
51
api/ambre-shield-v2.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/api/ambre-confidential-shield.js";
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
|
||||
// Replace the CONFIDENTIAL_IDS list with expanded version
|
||||
$old = "var CONFIDENTIAL_IDS = [
|
||||
'opus-pattern-badge', 'opus-pattern-style', 'opus-pattern-panel',
|
||||
'opus-udrill', 'opus-udrill-in', 'opus-dashboard-entry', 'opus-dashboard-link',
|
||||
'wtp-udock', 'v130-xnav', 'opus-xlinks', 'wtp-sidebar',
|
||||
'opus-claude-pattern', 'opus-dashboards',
|
||||
];";
|
||||
|
||||
$new = "var CONFIDENTIAL_IDS = [
|
||||
'opus-pattern-badge', 'opus-pattern-style', 'opus-pattern-panel',
|
||||
'opus-pattern-modal', 'opus-pattern-box', 'opus-pattern-close', 'opus-pattern-input',
|
||||
'opus-pattern-bot', 'opus-pattern-output', 'opus-pattern-content',
|
||||
'opus-pattern-launch', 'opus-pattern-send',
|
||||
'opus-udrill', 'opus-udrill-in', 'opus-dashboard-entry', 'opus-dashboard-link',
|
||||
'wtp-udock', 'v130-xnav', 'opus-xlinks', 'wtp-sidebar',
|
||||
'opus-claude-pattern', 'opus-dashboards',
|
||||
'archi-meta-badge', 'v130-floating-dock',
|
||||
];";
|
||||
|
||||
if (strpos($c, $old) === false) {
|
||||
echo json_encode(["error"=>"CONFIDENTIAL_IDS not found in shield"]);
|
||||
exit;
|
||||
}
|
||||
$c = str_replace($old, $new, $c);
|
||||
|
||||
// Also neutralize the window.__opusPatternOpen function (prevent opening)
|
||||
$old2 = "console.log('[ambre-confidential-shield] active on public page: ' + path);";
|
||||
$new2 = "// Neutralize global opusPatternOpen function (prevents programmatic opening)
|
||||
try {
|
||||
Object.defineProperty(window, '__opusPatternOpen', { value: function(){}, writable: false, configurable: false });
|
||||
Object.defineProperty(window, '__opusPatternClose', { value: function(){}, writable: false, configurable: false });
|
||||
} catch(e) {}
|
||||
|
||||
console.log('[ambre-confidential-shield] active on public page: ' + path);";
|
||||
|
||||
$c = str_replace($old2, $new2, $c);
|
||||
|
||||
$backup = "/opt/wevads/vault/shield.GOLD-" . date("Ymd-His") . "-wave262-v2";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $c);
|
||||
|
||||
echo json_encode([
|
||||
"delta" => strlen($c) - $orig,
|
||||
"wrote" => $wrote,
|
||||
]);
|
||||
15
api/ambre-sse2.php
Normal file
15
api/ambre-sse2.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$c = @file_get_contents("/var/www/html/wevia.html");
|
||||
echo "size: " . strlen($c) . "\n";
|
||||
echo "Claude count: " . substr_count($c, "Claude") . "\n";
|
||||
echo "WEVIA-pattern: " . preg_match_all("/WEVIA[- ]?[pP]attern/", $c) . "\n";
|
||||
|
||||
// Find around "phase" type handling
|
||||
$pos = strpos($c, "type === 'header'");
|
||||
if ($pos === false) $pos = strpos($c, 'type==="header"');
|
||||
if ($pos === false) $pos = strpos($c, "'header'");
|
||||
echo "header pos: $pos\n";
|
||||
if ($pos !== false) {
|
||||
echo substr($c, $pos, 2500);
|
||||
}
|
||||
11
api/ambre-sse3.php
Normal file
11
api/ambre-sse3.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$c = @file_get_contents("/var/www/html/wevia.html");
|
||||
|
||||
// Find WEVIA-pattern header rendering - that's the SSE handler for 'header' type
|
||||
$pos = strpos($c, "WEVIA-pattern");
|
||||
echo "WEVIA-pattern 1st at: $pos\n\n";
|
||||
if ($pos !== false) {
|
||||
echo "=== Context (go back to find handler start) ===\n";
|
||||
echo substr($c, max(0, $pos - 1500), 3000);
|
||||
}
|
||||
9
api/ambre-sse4.php
Normal file
9
api/ambre-sse4.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$c = @file_get_contents("/var/www/html/wevia.html");
|
||||
// Get the rest of handleEvent (from WEVIA-pattern onwards to end of function)
|
||||
$pos = strpos($c, "WEVIA-pattern");
|
||||
$end = strpos($c, "eventSource.close", $pos);
|
||||
if ($end === false) $end = $pos + 6000;
|
||||
echo "=== handleEvent from 96870 to " . ($pos + 6000) . " ===\n";
|
||||
echo substr($c, $pos + 1800, 5000);
|
||||
@@ -1,9 +1,19 @@
|
||||
<?php
|
||||
// V179 wevia-brand · all providers masked as WEVIA Vision · internal_engine kept for debug
|
||||
/**
|
||||
* ambre-tool-image.php · Real image generation via Pollinations.ai (free, no auth)
|
||||
* Returns downloadable PNG from prompt
|
||||
* V176 · ambre-tool-image.php · Upgraded with quality cascade
|
||||
* Yacine: "IMAGE POURRI MET A LOUVER QWEN IMAGE POUR AMELOIRER"
|
||||
*
|
||||
* Cascade (order by QUALITY):
|
||||
* 1. Gemini 3 Pro Image Preview (best quality, free tier via GEMINI_KEY) - PRIMARY
|
||||
* 2. Qwen-Image via DashScope (requires ALIBABA_KEY with credits)
|
||||
* 3. Pollinations flux (free, 1024x1024)
|
||||
* 4. Pollinations sana (free, 768x768 fast fallback)
|
||||
*
|
||||
* Keep backward compat: same response schema as before
|
||||
*/
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
set_time_limit(90);
|
||||
|
||||
$raw = file_get_contents("php://input");
|
||||
$in = json_decode($raw, true) ?: $_POST ?: $_GET;
|
||||
@@ -11,45 +21,189 @@ $prompt = trim($in["prompt"] ?? $in["q"] ?? "");
|
||||
|
||||
if (!$prompt) { echo json_encode(["error"=>"prompt required"]); exit; }
|
||||
|
||||
// Clean + translate prompt (keep as-is - Pollinations handles multilingue)
|
||||
$clean = preg_replace('/[^\p{L}\p{N}\s,.\-]/u', '', $prompt);
|
||||
$clean = substr(trim($clean), 0, 300);
|
||||
// Clean prompt (keep unicode)
|
||||
$clean = preg_replace('/[^\p{L}\p{N}\s,.\-!?]/u', '', $prompt);
|
||||
$clean = mb_substr(trim($clean), 0, 400);
|
||||
|
||||
// Pollinations API
|
||||
$seed = rand(1, 99999);
|
||||
$encoded = urlencode($clean);
|
||||
$pollinations_url = "https://image.pollinations.ai/prompt/$encoded?width=1024&height=1024&seed=$seed&nologo=true&enhance=true";
|
||||
|
||||
// Fetch image (with 30s timeout)
|
||||
$ctx = stream_context_create([
|
||||
"http" => ["timeout"=>30, "header"=>"User-Agent: WEVIA/1.0\r\n"],
|
||||
"https" => ["timeout"=>30, "header"=>"User-Agent: WEVIA/1.0\r\n"],
|
||||
]);
|
||||
$t0 = microtime(true);
|
||||
$img_data = @file_get_contents($pollinations_url, false, $ctx);
|
||||
$elapsed = round((microtime(true)-$t0)*1000);
|
||||
|
||||
if (!$img_data || strlen($img_data) < 1000) {
|
||||
echo json_encode(["error"=>"image generation failed", "prompt"=>$clean, "elapsed"=>$elapsed]);
|
||||
exit;
|
||||
// Load secrets
|
||||
$secrets = [];
|
||||
foreach (file("/etc/weval/secrets.env") ?: [] as $line) {
|
||||
$line = trim($line);
|
||||
if (!$line || $line[0] === "#" || strpos($line, "=") === false) continue;
|
||||
list($k, $v) = explode("=", $line, 2);
|
||||
$secrets[trim($k)] = trim($v, " \"'");
|
||||
}
|
||||
$GEMINI_KEY = $secrets["GEMINI_KEY"] ?? "";
|
||||
$ALIBABA_KEY = $secrets["ALIBABA_KEY"] ?? "";
|
||||
|
||||
// Save to /generated/
|
||||
// File naming (shared across cascade)
|
||||
$dir = "/var/www/html/generated";
|
||||
if (!is_dir($dir)) @mkdir($dir, 0755, true);
|
||||
$slug = preg_replace('/[^a-z0-9]+/', '-', strtolower($clean));
|
||||
$slug = substr(trim($slug, "-"), 0, 50);
|
||||
$ts = date("Ymd-His");
|
||||
$rand = bin2hex(random_bytes(3));
|
||||
$filename = "wevia-img-{$slug}-{$ts}-{$rand}.png";
|
||||
$path = "$dir/$filename";
|
||||
file_put_contents($path, $img_data);
|
||||
|
||||
echo json_encode([
|
||||
"success" => true,
|
||||
"prompt" => $clean,
|
||||
"url" => "https://weval-consulting.com/generated/$filename",
|
||||
"size_kb" => round(strlen($img_data)/1024, 1),
|
||||
"elapsed_ms" => $elapsed,
|
||||
"provider" => "WEVIA Image Engine",
|
||||
]);
|
||||
$t0 = microtime(true);
|
||||
$result = null;
|
||||
|
||||
// ========== TIER 1: Gemini 3 Pro Image Preview (best quality, free) ==========
|
||||
if ($GEMINI_KEY) {
|
||||
$gurl = "https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-image-preview:generateContent?key=" . $GEMINI_KEY;
|
||||
$body = json_encode([
|
||||
"contents" => [["parts" => [["text" => $clean]]]],
|
||||
"generationConfig" => ["responseModalities" => ["IMAGE", "TEXT"]],
|
||||
]);
|
||||
$ctx = stream_context_create([
|
||||
"http" => [
|
||||
"method" => "POST",
|
||||
"header" => "Content-Type: application/json\r\n",
|
||||
"content" => $body,
|
||||
"timeout" => 60,
|
||||
"ignore_errors" => true,
|
||||
],
|
||||
]);
|
||||
$resp = @file_get_contents($gurl, false, $ctx);
|
||||
if ($resp) {
|
||||
$d = @json_decode($resp, true);
|
||||
if (isset($d["candidates"][0]["content"]["parts"])) {
|
||||
foreach ($d["candidates"][0]["content"]["parts"] as $p) {
|
||||
if (isset($p["inlineData"]["data"])) {
|
||||
$mime = $p["inlineData"]["mimeType"] ?? "image/jpeg";
|
||||
$ext = strpos($mime, "png") !== false ? "png" : "jpg";
|
||||
$filename = "wevia-img-vision-{$slug}-{$ts}-{$rand}.{$ext}";
|
||||
$path = "$dir/$filename";
|
||||
$img = base64_decode($p["inlineData"]["data"]);
|
||||
if ($img && strlen($img) > 5000) {
|
||||
file_put_contents($path, $img);
|
||||
$result = [
|
||||
"success" => true,
|
||||
"prompt" => $clean,
|
||||
"url" => "https://weval-consulting.com/generated/$filename",
|
||||
"size_kb" => round(strlen($img)/1024, 1),
|
||||
"elapsed_ms" => round((microtime(true)-$t0)*1000),
|
||||
"provider" => "WEVIA Vision (premium)",
|
||||
"quality" => "premium",
|
||||
"engine" => "wevia-vision-v1",
|
||||
"internal_engine" => "gemini-3-pro",
|
||||
];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========== TIER 2: Qwen-Image via DashScope (if Gemini failed + ALIBABA_KEY) ==========
|
||||
if (!$result && $ALIBABA_KEY) {
|
||||
// Create async task
|
||||
$submit_ctx = stream_context_create([
|
||||
"http" => [
|
||||
"method" => "POST",
|
||||
"header" => "Authorization: Bearer $ALIBABA_KEY\r\nContent-Type: application/json\r\nX-DashScope-Async: enable\r\n",
|
||||
"content" => json_encode([
|
||||
"model" => "qwen-image",
|
||||
"input" => ["prompt" => $clean],
|
||||
"parameters" => ["size" => "1024*1024", "n" => 1],
|
||||
]),
|
||||
"timeout" => 15,
|
||||
"ignore_errors" => true,
|
||||
],
|
||||
]);
|
||||
$submit_resp = @file_get_contents("https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis", false, $submit_ctx);
|
||||
$submit_d = @json_decode($submit_resp, true);
|
||||
$task_id = $submit_d["output"]["task_id"] ?? "";
|
||||
if ($task_id) {
|
||||
// Poll
|
||||
for ($i = 0; $i < 20; $i++) {
|
||||
sleep(2);
|
||||
$pctx = stream_context_create(["http"=>["header"=>"Authorization: Bearer $ALIBABA_KEY\r\n","timeout"=>10]]);
|
||||
$pr = @file_get_contents("https://dashscope-intl.aliyuncs.com/api/v1/tasks/$task_id", false, $pctx);
|
||||
$pd = @json_decode($pr, true);
|
||||
$status = $pd["output"]["task_status"] ?? "";
|
||||
if ($status === "SUCCEEDED") {
|
||||
$img_url = $pd["output"]["results"][0]["url"] ?? "";
|
||||
if ($img_url) {
|
||||
$img = @file_get_contents($img_url);
|
||||
if ($img && strlen($img) > 5000) {
|
||||
$filename = "wevia-img-vision-{$slug}-{$ts}-{$rand}.png";
|
||||
$path = "$dir/$filename";
|
||||
file_put_contents($path, $img);
|
||||
$result = [
|
||||
"success" => true,
|
||||
"prompt" => $clean,
|
||||
"url" => "https://weval-consulting.com/generated/$filename",
|
||||
"size_kb" => round(strlen($img)/1024, 1),
|
||||
"elapsed_ms" => round((microtime(true)-$t0)*1000),
|
||||
"provider" => "WEVIA Vision (premium)",
|
||||
"quality" => "premium",
|
||||
"engine" => "wevia-vision-v1",
|
||||
"internal_engine" => "qwen-image",
|
||||
];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ($status === "FAILED" || $status === "UNKNOWN") break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========== TIER 3: Pollinations flux (free 1024x1024) ==========
|
||||
if (!$result) {
|
||||
$seed = rand(1, 99999);
|
||||
$encoded = urlencode($clean);
|
||||
// Try with flux model hint (even though list shows only sana, try anyway)
|
||||
$flux_url = "https://image.pollinations.ai/prompt/$encoded?width=1024&height=1024&seed=$seed&nologo=true&enhance=true&model=flux";
|
||||
$ctx2 = stream_context_create(["http"=>["timeout"=>30,"header"=>"User-Agent: WEVIA/2.0\r\n"]]);
|
||||
$img = @file_get_contents($flux_url, false, $ctx2);
|
||||
if ($img && strlen($img) > 5000) {
|
||||
$filename = "wevia-img-vision-{$slug}-{$ts}-{$rand}.jpg";
|
||||
$path = "$dir/$filename";
|
||||
file_put_contents($path, $img);
|
||||
$result = [
|
||||
"success" => true,
|
||||
"prompt" => $clean,
|
||||
"url" => "https://weval-consulting.com/generated/$filename",
|
||||
"size_kb" => round(strlen($img)/1024, 1),
|
||||
"elapsed_ms" => round((microtime(true)-$t0)*1000),
|
||||
"provider" => "WEVIA Vision (standard)",
|
||||
"quality" => "standard",
|
||||
"engine" => "wevia-vision-v1",
|
||||
"internal_engine" => "pollinations-flux",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// ========== TIER 4: Pollinations sana (last resort) ==========
|
||||
if (!$result) {
|
||||
$seed = rand(1, 99999);
|
||||
$encoded = urlencode($clean);
|
||||
$sana_url = "https://image.pollinations.ai/prompt/$encoded?width=1024&height=1024&seed=$seed&nologo=true&enhance=true";
|
||||
$ctx3 = stream_context_create(["http"=>["timeout"=>30,"header"=>"User-Agent: WEVIA/2.0\r\n"]]);
|
||||
$img = @file_get_contents($sana_url, false, $ctx3);
|
||||
if ($img && strlen($img) > 5000) {
|
||||
$filename = "wevia-img-vision-{$slug}-{$ts}-{$rand}.jpg";
|
||||
$path = "$dir/$filename";
|
||||
file_put_contents($path, $img);
|
||||
$result = [
|
||||
"success" => true,
|
||||
"prompt" => $clean,
|
||||
"url" => "https://weval-consulting.com/generated/$filename",
|
||||
"size_kb" => round(strlen($img)/1024, 1),
|
||||
"elapsed_ms" => round((microtime(true)-$t0)*1000),
|
||||
"provider" => "WEVIA Vision (basic)",
|
||||
"quality" => "basic",
|
||||
"engine" => "wevia-vision-v1",
|
||||
"internal_engine" => "pollinations-sana",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (!$result) {
|
||||
echo json_encode(["error"=>"all image providers failed","prompt"=>$clean]);
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
21
api/ambre-trace-leak.php
Normal file
21
api/ambre-trace-leak.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
// grep for opus-pattern-badge in /var/www/html
|
||||
$out["opus_pattern_sources"] = trim(@shell_exec("grep -lrE 'opus-pattern-badge|opus-pattern-style' /var/www/html --include='*.js' --include='*.html' --include='*.php' 2>/dev/null | head -10"));
|
||||
$out["opus_udrill_sources"] = trim(@shell_exec("grep -lrE 'opus-udrill|opus-dashboard-entry' /var/www/html --include='*.js' --include='*.html' --include='*.php' 2>/dev/null | head -10"));
|
||||
$out["wtp_dock_sources"] = trim(@shell_exec("grep -lrE 'WTP Global|ERP Global|Admin.*Droid|Orch.*WevCode' /var/www/html --include='*.js' --include='*.html' 2>/dev/null | head -10"));
|
||||
|
||||
// Read the opus-pattern injector
|
||||
$f = @shell_exec("grep -lrE 'opus-pattern-badge' /var/www/html --include='*.js' --include='*.php' 2>/dev/null | head -1");
|
||||
$f = trim($f);
|
||||
if ($f && file_exists($f)) {
|
||||
$c = @file_get_contents($f);
|
||||
$out["pattern_injector_file"] = $f;
|
||||
$out["pattern_injector_has_guard"] = strpos($c, "PUBLIC-GUARD") !== false || strpos($c, "public_paths") !== false || strpos($c, "AMBRE-V1") !== false;
|
||||
// Extract first 300 chars
|
||||
$out["pattern_injector_head"] = substr($c, 0, 400);
|
||||
}
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
179
api/ambre-universal-chat.js
Normal file
179
api/ambre-universal-chat.js
Normal file
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* ambre-universal-chat.js · wave-259 · Universal chat widget for all internal pages
|
||||
*
|
||||
* Usage: just <script src="/api/ambre-universal-chat.js"></script>
|
||||
* - Auto-creates minimal chat UI (floating button + panel)
|
||||
* - Uses /api/ambre-internal-chat-api.php (persistent memory + cross-chat learning)
|
||||
* - Auto chat_id = hostname + pathname
|
||||
* - Works on wevia-master, all-ia-hub, orchestrator, director-chat, l99-brain, etc.
|
||||
*/
|
||||
(function(){
|
||||
if (window.__ambreUniversalChat) return;
|
||||
window.__ambreUniversalChat = true;
|
||||
|
||||
var chatId = "internal-" + (location.pathname.replace(/[^a-z0-9]/gi, "-").toLowerCase() || "root");
|
||||
var apiUrl = "/api/ambre-internal-chat-api.php";
|
||||
|
||||
// Styles
|
||||
var style = document.createElement("style");
|
||||
style.textContent = `
|
||||
.amw-btn{position:fixed;bottom:20px;right:20px;width:56px;height:56px;border-radius:50%;
|
||||
background:linear-gradient(135deg,#4338ca,#6366f1);color:#fff;border:none;cursor:pointer;
|
||||
box-shadow:0 4px 20px rgba(99,102,241,.4);z-index:99997;font-size:24px;transition:transform .15s}
|
||||
.amw-btn:hover{transform:scale(1.08)}
|
||||
.amw-panel{position:fixed;bottom:90px;right:20px;width:400px;max-width:calc(100vw - 40px);
|
||||
height:560px;max-height:calc(100vh - 120px);background:#fff;border-radius:16px;
|
||||
box-shadow:0 20px 60px rgba(0,0,0,.25);z-index:99998;display:none;flex-direction:column;
|
||||
overflow:hidden;font-family:system-ui,-apple-system,sans-serif}
|
||||
.amw-panel.open{display:flex;animation:amwSlide .2s ease}
|
||||
@keyframes amwSlide{from{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}
|
||||
.amw-header{padding:14px 16px;background:linear-gradient(135deg,#4338ca,#6366f1);color:#fff;
|
||||
display:flex;justify-content:space-between;align-items:center}
|
||||
.amw-header h3{margin:0;font-size:14px;font-weight:600}
|
||||
.amw-header .meta{font-size:11px;opacity:.85;margin-top:2px}
|
||||
.amw-close{background:transparent;border:none;color:#fff;font-size:20px;cursor:pointer;padding:0 4px}
|
||||
.amw-body{flex:1;overflow-y:auto;padding:14px;background:#f8fafc}
|
||||
.amw-msg{margin:8px 0;padding:10px 12px;border-radius:12px;max-width:85%;font-size:13px;line-height:1.4;word-wrap:break-word}
|
||||
.amw-msg.u{background:#eef2ff;color:#1e293b;margin-left:auto;border-bottom-right-radius:4px}
|
||||
.amw-msg.a{background:#fff;color:#1e293b;border:1px solid #e2e8f0;border-bottom-left-radius:4px}
|
||||
.amw-msg.a .meta{font-size:10px;color:#94a3b8;margin-top:4px}
|
||||
.amw-msg.a.ma{background:linear-gradient(135deg,#f0f9ff,#eef2ff);border-color:#6366f1}
|
||||
.amw-msg.a.ma::before{content:"🧠 Multi-Agent";display:block;font-size:10px;color:#4338ca;font-weight:600;margin-bottom:4px}
|
||||
.amw-input-wrap{padding:10px;background:#fff;border-top:1px solid #e2e8f0;display:flex;gap:8px}
|
||||
.amw-input{flex:1;padding:10px 12px;border:1px solid #cbd5e1;border-radius:10px;font-size:13px;outline:none;font-family:inherit}
|
||||
.amw-input:focus{border-color:#6366f1}
|
||||
.amw-send{padding:0 16px;background:linear-gradient(135deg,#4338ca,#6366f1);color:#fff;border:none;border-radius:10px;cursor:pointer;font-size:13px;font-weight:500}
|
||||
.amw-send:disabled{opacity:.5;cursor:not-allowed}
|
||||
.amw-typing{padding:10px;font-size:11px;color:#94a3b8;font-style:italic}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
// Elements
|
||||
var btn = document.createElement("button");
|
||||
btn.className = "amw-btn";
|
||||
btn.innerHTML = "💬";
|
||||
btn.title = "Chat interne WEVIA · mémoire persistante";
|
||||
document.body.appendChild(btn);
|
||||
|
||||
var panel = document.createElement("div");
|
||||
panel.className = "amw-panel";
|
||||
panel.innerHTML = `
|
||||
<div class="amw-header">
|
||||
<div>
|
||||
<h3>💬 Chat Interne · WEVIA</h3>
|
||||
<div class="meta">Mémoire persistante · Multi-agent · <span id="amwTurns">0</span> tours</div>
|
||||
</div>
|
||||
<button class="amw-close">✕</button>
|
||||
</div>
|
||||
<div class="amw-body" id="amwBody"></div>
|
||||
<div class="amw-input-wrap">
|
||||
<input class="amw-input" id="amwInput" placeholder="Écrivez (analyse complete pour multi-agent)..." />
|
||||
<button class="amw-send" id="amwSend">Envoyer</button>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(panel);
|
||||
|
||||
btn.addEventListener("click", function(){ panel.classList.toggle("open"); });
|
||||
panel.querySelector(".amw-close").addEventListener("click", function(){ panel.classList.remove("open"); });
|
||||
|
||||
var body = panel.querySelector("#amwBody");
|
||||
var input = panel.querySelector("#amwInput");
|
||||
var sendBtn = panel.querySelector("#amwSend");
|
||||
var turnsSpan = panel.querySelector("#amwTurns");
|
||||
|
||||
function addMsg(role, text, meta){
|
||||
var m = document.createElement("div");
|
||||
m.className = "amw-msg " + (role === "user" ? "u" : "a") + (meta && meta.mode === "multiagent" ? " ma" : "");
|
||||
var safe = (text || "").replace(/</g,"<").replace(/\n/g,"<br>");
|
||||
m.innerHTML = safe;
|
||||
if (meta && role === "assistant") {
|
||||
var mi = document.createElement("div");
|
||||
mi.className = "meta";
|
||||
mi.textContent = (meta.total_ms || 0) + "ms · " + (meta.mode || "std") + (meta.agents ? " · " + meta.agents + " agents" : "");
|
||||
m.appendChild(mi);
|
||||
}
|
||||
body.appendChild(m);
|
||||
body.scrollTop = body.scrollHeight;
|
||||
}
|
||||
|
||||
function showTyping(){
|
||||
var t = document.createElement("div");
|
||||
t.id = "amwTyping";
|
||||
t.className = "amw-typing";
|
||||
t.textContent = "WEVIA réfléchit...";
|
||||
body.appendChild(t);
|
||||
body.scrollTop = body.scrollHeight;
|
||||
}
|
||||
function hideTyping(){
|
||||
var t = document.getElementById("amwTyping");
|
||||
if (t) t.remove();
|
||||
}
|
||||
|
||||
function send(){
|
||||
var msg = input.value.trim();
|
||||
if (!msg) return;
|
||||
input.value = "";
|
||||
sendBtn.disabled = true;
|
||||
addMsg("user", msg);
|
||||
showTyping();
|
||||
|
||||
var ctrl = new AbortController();
|
||||
var timeout = setTimeout(function(){ ctrl.abort(); }, 120000);
|
||||
|
||||
fetch(apiUrl, {
|
||||
method: "POST",
|
||||
headers: {"Content-Type":"application/json","Cache-Control":"no-cache"},
|
||||
body: JSON.stringify({ chat_id: chatId, message: msg }),
|
||||
signal: ctrl.signal,
|
||||
cache: "no-store",
|
||||
})
|
||||
.then(function(r){ clearTimeout(timeout); return r.json(); })
|
||||
.then(function(d){
|
||||
hideTyping();
|
||||
sendBtn.disabled = false;
|
||||
if (d && d.ok) {
|
||||
addMsg("assistant", d.response || "(empty)", {
|
||||
mode: d.mode,
|
||||
total_ms: d.total_ms,
|
||||
agents: d.agents ? d.agents.length : 0,
|
||||
});
|
||||
turnsSpan.textContent = d.memory_turns || 0;
|
||||
} else {
|
||||
addMsg("assistant", "❌ " + ((d && d.error) || "Erreur"));
|
||||
}
|
||||
})
|
||||
.catch(function(err){
|
||||
hideTyping();
|
||||
sendBtn.disabled = false;
|
||||
addMsg("assistant", "❌ " + (err.name === "AbortError" ? "Timeout 2min" : String(err)));
|
||||
});
|
||||
}
|
||||
|
||||
sendBtn.addEventListener("click", send);
|
||||
input.addEventListener("keydown", function(e){ if (e.key === "Enter" && !e.shiftKey){ e.preventDefault(); send(); } });
|
||||
|
||||
// Load prior context on open
|
||||
var loaded = false;
|
||||
btn.addEventListener("click", function(){
|
||||
if (loaded || !panel.classList.contains("open")) return;
|
||||
loaded = true;
|
||||
fetch("/api/ambre-internal-memory.php", {
|
||||
method: "POST",
|
||||
headers: {"Content-Type":"application/json"},
|
||||
body: JSON.stringify({ action: "load", chat_id: chatId, n: 20 }),
|
||||
cache: "no-store",
|
||||
})
|
||||
.then(function(r){ return r.json(); })
|
||||
.then(function(d){
|
||||
if (d && d.ok && d.messages && d.messages.length > 0) {
|
||||
d.messages.forEach(function(m){
|
||||
if (m.role === "user" || m.role === "assistant") addMsg(m.role, m.content, m.metadata);
|
||||
});
|
||||
turnsSpan.textContent = d.messages.length;
|
||||
} else {
|
||||
addMsg("assistant", "Bonjour ! Je suis WEVIA interne (mémoire persistante illimitée). Chat_id: " + chatId);
|
||||
}
|
||||
})
|
||||
.catch(function(){});
|
||||
});
|
||||
})();
|
||||
17
api/ambre-widget-read.php
Normal file
17
api/ambre-widget-read.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$c = @file_get_contents("/var/www/html/wevia-widget.html");
|
||||
// Find Claude Pattern context
|
||||
$pos = strpos($c, "Claude Pattern");
|
||||
if ($pos !== false) {
|
||||
echo "=== Claude Pattern ctx ===\n";
|
||||
echo substr($c, max(0, $pos - 300), 600);
|
||||
}
|
||||
echo "\n\n=== WTP ctx ===\n";
|
||||
$pos2 = strpos($c, "WTP");
|
||||
if ($pos2 !== false) echo substr($c, max(0, $pos2 - 300), 700);
|
||||
|
||||
echo "\n\n=== All script srcs and inline signatures ===\n";
|
||||
preg_match_all('/<script[^>]*(?:src=["\']([^"\']+)["\']|>([^<]{0,100}))/', $c, $m);
|
||||
foreach ($m[1] as $s) if ($s) echo "SRC: $s\n";
|
||||
foreach ($m[2] as $s) if (trim($s)) echo "INLINE: " . substr(trim($s), 0, 100) . "\n";
|
||||
53
api/ambre-widget-trace.php
Normal file
53
api/ambre-widget-trace.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$root = @file_get_contents("/var/www/html/index.html");
|
||||
|
||||
// Find all widgets + iframes + the chatbot/claude-pattern widget
|
||||
$out = [];
|
||||
|
||||
// Search for specific widget signatures in index.html
|
||||
$sigs = [
|
||||
"claude-pattern",
|
||||
"Claude Pattern",
|
||||
"WTP",
|
||||
"IA Hub",
|
||||
"Master",
|
||||
"Droid",
|
||||
"Arena",
|
||||
"WEVIA Engine",
|
||||
"WevCode",
|
||||
"widget.js",
|
||||
"chat-widget",
|
||||
"Ouvrir en plein ecran",
|
||||
"weval-chat-fix",
|
||||
"wevia-widget",
|
||||
"chat-fix",
|
||||
];
|
||||
foreach ($sigs as $s) {
|
||||
$out["match_$s"] = substr_count($root, $s);
|
||||
}
|
||||
$out["root_size"] = strlen($root);
|
||||
|
||||
// All <script src>
|
||||
preg_match_all('/<script[^>]*src=["\']([^"\']+)["\']/', $root, $m);
|
||||
$out["scripts"] = array_unique($m[1] ?? []);
|
||||
|
||||
// Check weval-chat-fix.js content
|
||||
$cf = @file_get_contents("/var/www/html/weval-chat-fix.js");
|
||||
if ($cf) {
|
||||
$out["chat_fix_size"] = strlen($cf);
|
||||
$out["chat_fix_has_wtp"] = substr_count($cf, "WTP");
|
||||
$out["chat_fix_has_claude_pattern"] = substr_count($cf, "Claude Pattern");
|
||||
$out["chat_fix_has_Master"] = substr_count($cf, "Master") + substr_count($cf, "IA Hub");
|
||||
$out["chat_fix_head_200"] = substr($cf, 0, 400);
|
||||
}
|
||||
|
||||
// Also check wevia-widget
|
||||
$ww = @file_get_contents("/var/www/html/wevia-widget.html");
|
||||
if ($ww) {
|
||||
$out["wevia_widget_size"] = strlen($ww);
|
||||
$out["wevia_widget_has_dock"] = substr_count($ww, "WTP") + substr_count($ww, "Master") + substr_count($ww, "Droid");
|
||||
$out["wevia_widget_has_claude_pattern"] = substr_count($ww, "Claude Pattern");
|
||||
}
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
184
api/ambre-xlsx-gen.php
Normal file
184
api/ambre-xlsx-gen.php
Normal file
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
/**
|
||||
* V174 · ambre-xlsx-gen.php
|
||||
* Real XLSX generation using Python openpyxl via shell_exec
|
||||
* Yacine: Excel KO · genere docx au lieu xlsx
|
||||
* Cause: ambre-xlsx-gen.php missing, fallback to docx
|
||||
* Fix: this file generates real xlsx via openpyxl (already installed)
|
||||
*/
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
set_time_limit(60);
|
||||
$t0 = microtime(true);
|
||||
|
||||
$topic = trim($_GET["topic"] ?? $_POST["topic"] ?? "");
|
||||
if (!$topic) {
|
||||
echo json_encode(["error"=>"topic required"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// 1. Use LLM to generate JSON structure for the spreadsheet
|
||||
$sys = "Tu es generateur de donnees spreadsheet. Reponds UNIQUEMENT avec JSON valide, pas de markdown. Schema: {\"sheet_name\":\"...\",\"headers\":[\"col1\",\"col2\",...],\"rows\":[[\"val1\",\"val2\",...],...],\"kpis\":{\"metric\":\"value\",...}}. MAX 8 columns, 15 rows. Donnees realistes en francais avec chiffres et pourcentages.";
|
||||
$user = "Genere donnees spreadsheet pour: $topic";
|
||||
$llm_raw = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
|
||||
"http" => [
|
||||
"method" => "POST",
|
||||
"header" => "Content-Type: application/json\r\n",
|
||||
"content" => json_encode([
|
||||
"model" => "fast",
|
||||
"messages" => [
|
||||
["role"=>"system","content"=>$sys],
|
||||
["role"=>"user","content"=>$user],
|
||||
],
|
||||
"max_tokens" => 1200,
|
||||
"temperature" => 0.3,
|
||||
]),
|
||||
"timeout" => 30,
|
||||
],
|
||||
]));
|
||||
$llm_d = @json_decode($llm_raw, true);
|
||||
$content = $llm_d["choices"][0]["message"]["content"] ?? "";
|
||||
$content = trim(preg_replace("/```(?:json)?\n?|```/", "", $content));
|
||||
|
||||
// Parse JSON
|
||||
$data = @json_decode($content, true);
|
||||
if (!$data || !isset($data["headers"]) || !isset($data["rows"])) {
|
||||
// Fallback minimal
|
||||
$data = [
|
||||
"sheet_name" => mb_substr($topic, 0, 30),
|
||||
"headers" => ["Categorie", "Valeur", "Pourcentage"],
|
||||
"rows" => [
|
||||
["Donnee 1", 100, "25%"],
|
||||
["Donnee 2", 200, "50%"],
|
||||
["Donnee 3", 300, "75%"],
|
||||
],
|
||||
"kpis" => ["Total"=>"600","Moyenne"=>"200"],
|
||||
];
|
||||
}
|
||||
|
||||
// 2. Call Python script to generate xlsx
|
||||
$slug = preg_replace("/[^a-z0-9-]/", "-", strtolower($topic));
|
||||
$slug = trim(preg_replace("/-+/", "-", $slug), "-");
|
||||
$slug = mb_substr($slug, 0, 40);
|
||||
$filename = "wevia-xlsx-" . $slug . "-" . date("Ymd-His") . "-" . substr(md5($topic.rand()), 0, 6) . ".xlsx";
|
||||
$filepath = "/var/www/html/generated/" . $filename;
|
||||
|
||||
// JSON data file for Python to read (avoid shell escaping issues)
|
||||
$json_tmp = "/tmp/wevia-xlsx-" . uniqid() . ".json";
|
||||
file_put_contents($json_tmp, json_encode($data, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
$py_script = <<<'PYEND'
|
||||
import json, sys, openpyxl
|
||||
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
|
||||
from openpyxl.chart import BarChart, Reference
|
||||
json_file = sys.argv[1]
|
||||
xlsx_out = sys.argv[2]
|
||||
topic = sys.argv[3]
|
||||
with open(json_file) as f:
|
||||
data = json.load(f)
|
||||
wb = openpyxl.Workbook()
|
||||
ws = wb.active
|
||||
ws.title = (data.get("sheet_name") or topic[:30])[:30]
|
||||
# Header styling
|
||||
header_font = Font(bold=True, color="FFFFFF", size=12)
|
||||
header_fill = PatternFill(start_color="6366F1", end_color="6366F1", fill_type="solid")
|
||||
header_align = Alignment(horizontal="center", vertical="center")
|
||||
# Title row
|
||||
ws["A1"] = topic
|
||||
ws["A1"].font = Font(bold=True, size=16, color="4338CA")
|
||||
ws["A1"].alignment = Alignment(horizontal="left", vertical="center")
|
||||
ws.row_dimensions[1].height = 30
|
||||
# Headers row 3
|
||||
headers = data.get("headers", [])
|
||||
for i, h in enumerate(headers):
|
||||
cell = ws.cell(row=3, column=i+1, value=h)
|
||||
cell.font = header_font
|
||||
cell.fill = header_fill
|
||||
cell.alignment = header_align
|
||||
# Data rows
|
||||
rows = data.get("rows", [])
|
||||
for ri, row in enumerate(rows):
|
||||
for ci, val in enumerate(row):
|
||||
c = ws.cell(row=4+ri, column=ci+1, value=val)
|
||||
c.alignment = Alignment(vertical="center")
|
||||
if ri % 2 == 0:
|
||||
c.fill = PatternFill(start_color="F1F5F9", end_color="F1F5F9", fill_type="solid")
|
||||
# Column widths
|
||||
for i, h in enumerate(headers):
|
||||
ws.column_dimensions[chr(65+i)].width = max(15, len(str(h))+5)
|
||||
# KPIs section
|
||||
kpi_row = 4 + len(rows) + 2
|
||||
kpis = data.get("kpis", {})
|
||||
if kpis:
|
||||
kpi_cell = ws.cell(row=kpi_row, column=1, value="KPIs")
|
||||
kpi_cell.font = Font(bold=True, size=14, color="4338CA")
|
||||
for i, (k, v) in enumerate(kpis.items()):
|
||||
ws.cell(row=kpi_row+1+i, column=1, value=k).font = Font(bold=True)
|
||||
ws.cell(row=kpi_row+1+i, column=2, value=v)
|
||||
# Add chart if numeric data
|
||||
try:
|
||||
numeric_col = None
|
||||
for ci, h in enumerate(headers):
|
||||
if any(isinstance(r[ci], (int, float)) if ci < len(r) else False for r in rows):
|
||||
numeric_col = ci
|
||||
break
|
||||
if numeric_col is not None and len(rows) > 0:
|
||||
chart = BarChart()
|
||||
chart.title = "Visualisation"
|
||||
chart.style = 13
|
||||
data_ref = Reference(ws, min_col=numeric_col+1, min_row=3, max_row=3+len(rows), max_col=numeric_col+1)
|
||||
cats_ref = Reference(ws, min_col=1, min_row=4, max_row=3+len(rows))
|
||||
chart.add_data(data_ref, titles_from_data=True)
|
||||
chart.set_categories(cats_ref)
|
||||
chart.width = 15
|
||||
chart.height = 8
|
||||
ws.add_chart(chart, f"E{kpi_row}")
|
||||
except Exception as e:
|
||||
print(f"Chart error: {e}", file=sys.stderr)
|
||||
wb.save(xlsx_out)
|
||||
print("OK")
|
||||
PYEND;
|
||||
|
||||
$py_tmp = "/tmp/wevia-xlsx-gen-" . uniqid() . ".py";
|
||||
file_put_contents($py_tmp, $py_script);
|
||||
|
||||
$cmd = "python3 " . escapeshellarg($py_tmp) . " " . escapeshellarg($json_tmp) . " " . escapeshellarg($filepath) . " " . escapeshellarg($topic) . " 2>&1";
|
||||
$out = shell_exec($cmd);
|
||||
@unlink($py_tmp);
|
||||
@unlink($json_tmp);
|
||||
|
||||
if (!file_exists($filepath) || filesize($filepath) < 100) {
|
||||
echo json_encode(["error"=>"xlsx generation failed","python_out"=>$out]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$size = filesize($filepath);
|
||||
$elapsed = round((microtime(true) - $t0) * 1000);
|
||||
$full_url = "https://weval-consulting.com/generated/" . $filename;
|
||||
|
||||
// Build preview text
|
||||
$preview = "📊 **" . $topic . "** (Excel reel avec graphique)\n\n";
|
||||
$preview .= "Feuille: " . ($data["sheet_name"] ?? $topic) . "\n";
|
||||
$preview .= "Colonnes: " . count($data["headers"] ?? []) . " · Lignes: " . count($data["rows"] ?? []) . "\n";
|
||||
if (!empty($data["kpis"])) {
|
||||
$preview .= "\nKPIs:\n";
|
||||
foreach ($data["kpis"] as $k => $v) {
|
||||
$preview .= "- **$k**: $v\n";
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
"ok" => true,
|
||||
"url" => "/generated/" . $filename,
|
||||
"full_url" => $full_url,
|
||||
"size_bytes" => $size,
|
||||
"size_human" => round($size/1024, 1) . "KB",
|
||||
"elapsed_ms" => $elapsed,
|
||||
"engine" => "openpyxl",
|
||||
"provider" => "WEVIA XLSX Engine V174",
|
||||
"topic" => $topic,
|
||||
"preview" => $preview,
|
||||
"sheet_name" => $data["sheet_name"] ?? $topic,
|
||||
"rows_count" => count($data["rows"] ?? []),
|
||||
"columns_count" => count($data["headers"] ?? []),
|
||||
"has_chart" => true,
|
||||
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generated": "2026-04-22 02:30:02",
|
||||
"generated": "2026-04-23 17:30:02",
|
||||
"version": "1.0",
|
||||
"servers": [
|
||||
{
|
||||
@@ -8,9 +8,9 @@
|
||||
"private": "10.1.0.2",
|
||||
"role": "PRIMARY",
|
||||
"ssh": 49222,
|
||||
"disk_pct": 85,
|
||||
"disk_avail": "22G",
|
||||
"uptime": "up 1 week, 16 hours, 38 minutes",
|
||||
"disk_pct": 86,
|
||||
"disk_avail": "21G",
|
||||
"uptime": "up 1 week, 2 days, 7 hours, 38 minutes",
|
||||
"nginx": "active",
|
||||
"php_fpm": "active",
|
||||
"php_version": "8.5.5"
|
||||
@@ -21,8 +21,8 @@
|
||||
"private": "10.1.0.3",
|
||||
"role": "WEVADS Arsenal",
|
||||
"ssh": 22,
|
||||
"disk_pct": 82,
|
||||
"disk_avail": "26G",
|
||||
"disk_pct": 87,
|
||||
"disk_avail": "20G",
|
||||
"sentinel": 1
|
||||
},
|
||||
{
|
||||
@@ -34,108 +34,103 @@
|
||||
}
|
||||
],
|
||||
"docker": [
|
||||
{
|
||||
"name": "weval-docuseal",
|
||||
"status": "Up Less than a second",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "loki",
|
||||
"status": "Up 5 days",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "listmonk",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "plausible-plausible-1",
|
||||
"status": "Up 4 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "plausible-plausible-db-1",
|
||||
"status": "Up 4 days",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "plausible-plausible-events-db-1",
|
||||
"status": "Up 4 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "n8n-docker-n8n-1",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "mattermost-docker-mm-db-1",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "mattermost-docker-mattermost-1",
|
||||
"status": "Up 5 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "twenty",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "twenty-redis",
|
||||
"status": "Up 5 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "langfuse",
|
||||
"status": "Up 6 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "redis-weval",
|
||||
"name": "n8n-docker-n8n-1",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "gitea",
|
||||
"name": "mattermost-docker-mm-db-1",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "node-exporter",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "prometheus",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "searxng",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "uptime-kuma",
|
||||
"status": "Up 2 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "vaultwarden",
|
||||
"name": "mattermost-docker-mattermost-1",
|
||||
"status": "Up 7 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "qdrant",
|
||||
"name": "twenty",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "twenty-redis",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "langfuse",
|
||||
"status": "Up 7 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "redis-weval",
|
||||
"status": "Up 9 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "gitea",
|
||||
"status": "Up 9 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "node-exporter",
|
||||
"status": "Up 9 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "prometheus",
|
||||
"status": "Up 9 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "searxng",
|
||||
"status": "Up 9 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "uptime-kuma",
|
||||
"status": "Up 3 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "vaultwarden",
|
||||
"status": "Up 9 days (healthy)",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "qdrant",
|
||||
"status": "Up 9 days",
|
||||
"ports": ""
|
||||
}
|
||||
],
|
||||
"domains": [
|
||||
{
|
||||
"file": "ai.weval-consulting.com",
|
||||
"server_names": [
|
||||
"ai.weval-consulting.com"
|
||||
],
|
||||
"ssl": true,
|
||||
"php-session": false,
|
||||
"php-session_paths": false,
|
||||
"auth_complete": false
|
||||
},
|
||||
{
|
||||
"file": "analytics.weval-consulting.com",
|
||||
"server_names": [
|
||||
@@ -280,9 +275,9 @@
|
||||
}
|
||||
],
|
||||
"screens": {
|
||||
"s204_html": 324,
|
||||
"s204_html": 331,
|
||||
"s204_products": 104,
|
||||
"s204_api_php": 1012,
|
||||
"s204_api_php": 1080,
|
||||
"s204_wevia_php": 254,
|
||||
"s95_arsenal_html": 1377,
|
||||
"s95_arsenal_api": 377
|
||||
@@ -302,11 +297,11 @@
|
||||
"mattermost_db",
|
||||
"deerflow",
|
||||
"nocodb",
|
||||
"paperclip",
|
||||
"langfuse"
|
||||
"langfuse",
|
||||
"paperclip"
|
||||
],
|
||||
"key_tables": {
|
||||
"kb_learnings": 5615,
|
||||
"kb_learnings": 6206,
|
||||
"kb_documents": 0,
|
||||
"ethica_medecins": 50004,
|
||||
"enterprise_agents": 0
|
||||
@@ -418,7 +413,7 @@
|
||||
},
|
||||
{
|
||||
"name": "wevia_memory_768",
|
||||
"vectors": 87
|
||||
"vectors": 100
|
||||
},
|
||||
{
|
||||
"name": "wevia_kb_768",
|
||||
@@ -606,15 +601,15 @@
|
||||
]
|
||||
},
|
||||
"wiki": {
|
||||
"total_entries": 5615,
|
||||
"total_entries": 6206,
|
||||
"categories": [
|
||||
{
|
||||
"category": "AUTO-FIX",
|
||||
"cnt": "3018"
|
||||
"cnt": "3529"
|
||||
},
|
||||
{
|
||||
"category": "TOPOLOGY",
|
||||
"cnt": "1241"
|
||||
"cnt": "1321"
|
||||
},
|
||||
{
|
||||
"category": "DISCOVERY",
|
||||
@@ -1714,54 +1709,54 @@
|
||||
"fast_lines": 3718,
|
||||
"router_lines": 6152,
|
||||
"router_functions": 17,
|
||||
"today_requests": 0,
|
||||
"today_requests": 1,
|
||||
"today_cost": 0,
|
||||
"avg_latency_ms": 0,
|
||||
"top_provider": "N\/A",
|
||||
"providers_used": 0
|
||||
"avg_latency_ms": 1257,
|
||||
"top_provider": "WEVIA Engine",
|
||||
"providers_used": 1
|
||||
},
|
||||
"optimizations": {
|
||||
"recent_commits": [],
|
||||
"auto_fixes": [
|
||||
{
|
||||
"fact": "AUTONOMY 22Apr 02:25: 1 fixes. Disk light cleanup 86%",
|
||||
"created_at": "2026-04-22 04:25:07.944997"
|
||||
"fact": "AUTONOMY 23Apr 17:25: 1 fixes. Disk light cleanup 86%",
|
||||
"created_at": "2026-04-23 19:25:05.748581"
|
||||
},
|
||||
{
|
||||
"fact": "AUTONOMY 22Apr 02:20: 1 fixes. Disk light cleanup 85%",
|
||||
"created_at": "2026-04-22 04:20:05.987441"
|
||||
"fact": "AUTONOMY 23Apr 17:20: 1 fixes. Disk light cleanup 86%",
|
||||
"created_at": "2026-04-23 19:20:06.842128"
|
||||
},
|
||||
{
|
||||
"fact": "AUTONOMY 22Apr 02:15: 1 fixes. Disk light cleanup 85%",
|
||||
"created_at": "2026-04-22 04:15:06.951973"
|
||||
"fact": "AUTONOMY 23Apr 17:15: 1 fixes. Disk light cleanup 86%",
|
||||
"created_at": "2026-04-23 19:15:10.148566"
|
||||
},
|
||||
{
|
||||
"fact": "AUTONOMY 22Apr 02:10: 1 fixes. Disk light cleanup 85%",
|
||||
"created_at": "2026-04-22 04:10:05.81299"
|
||||
"fact": "AUTONOMY 23Apr 17:10: 1 fixes. Disk light cleanup 86%",
|
||||
"created_at": "2026-04-23 19:10:08.301141"
|
||||
},
|
||||
{
|
||||
"fact": "AUTONOMY 22Apr 02:05: 2 fixes. Disk light cleanup 85%; Docker restart weval-docuseal",
|
||||
"created_at": "2026-04-22 04:05:05.713752"
|
||||
"fact": "AUTONOMY 23Apr 17:05: 1 fixes. Disk light cleanup 86%",
|
||||
"created_at": "2026-04-23 19:05:07.873958"
|
||||
},
|
||||
{
|
||||
"fact": "AUTONOMY 22Apr 02:00: 1 fixes. Disk light cleanup 85%",
|
||||
"created_at": "2026-04-22 04:00:12.712547"
|
||||
"fact": "AUTONOMY 23Apr 17:00: 1 fixes. Disk light cleanup 86%",
|
||||
"created_at": "2026-04-23 19:00:13.590172"
|
||||
},
|
||||
{
|
||||
"fact": "AUTONOMY 22Apr 01:55: 1 fixes. Disk light cleanup 85%",
|
||||
"created_at": "2026-04-22 03:55:05.962118"
|
||||
"fact": "AUTONOMY 23Apr 16:55: 1 fixes. Disk light cleanup 86%",
|
||||
"created_at": "2026-04-23 18:55:07.496828"
|
||||
},
|
||||
{
|
||||
"fact": "AUTONOMY 22Apr 01:50: 1 fixes. Disk light cleanup 85%",
|
||||
"created_at": "2026-04-22 03:50:06.817088"
|
||||
"fact": "AUTONOMY 23Apr 16:50: 1 fixes. Disk light cleanup 86%",
|
||||
"created_at": "2026-04-23 18:50:08.904226"
|
||||
},
|
||||
{
|
||||
"fact": "AUTONOMY 22Apr 01:45: 1 fixes. Disk light cleanup 85%",
|
||||
"created_at": "2026-04-22 03:45:05.349235"
|
||||
"fact": "AUTONOMY 23Apr 16:45: 1 fixes. Disk light cleanup 86%",
|
||||
"created_at": "2026-04-23 18:45:10.364862"
|
||||
},
|
||||
{
|
||||
"fact": "AUTONOMY 22Apr 01:40: 1 fixes. Disk light cleanup 85%",
|
||||
"created_at": "2026-04-22 03:40:06.63822"
|
||||
"fact": "AUTONOMY 23Apr 16:40: 1 fixes. Disk light cleanup 86%",
|
||||
"created_at": "2026-04-23 18:40:10.055969"
|
||||
}
|
||||
],
|
||||
"architecture_decisions": [
|
||||
@@ -1943,14 +1938,14 @@
|
||||
{
|
||||
"severity": "opportunity",
|
||||
"category": "SCALABILITY",
|
||||
"title": "Qdrant: 22,110 vecteurs",
|
||||
"title": "Qdrant: 22,123 vecteurs",
|
||||
"detail": "Volume vectoriel croissant. Planifier sharding ou migration vers cluster Qdrant.",
|
||||
"action": "opportunity",
|
||||
"fix_cmd": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"scan_time_ms": 2870,
|
||||
"scan_time_ms": 3913,
|
||||
"gaps": [],
|
||||
"score": 100,
|
||||
"automation": {
|
||||
|
||||
@@ -1,10 +1,49 @@
|
||||
<?php
|
||||
// Opus v19 · Auth check with agent bypass token
|
||||
// - Fallback: PHP session (existing behavior · no regression)
|
||||
// - NEW: X-Agent-Token header OR ?_agent_token= param
|
||||
// - Validated against /etc/weval/secrets.env AGENT_TOKEN (or fallback to DROID2026)
|
||||
|
||||
session_set_cookie_params(["lifetime"=>86400,"path"=>"/","domain"=>".weval-consulting.com","secure"=>true,"httponly"=>true,"samesite"=>"Lax"]);
|
||||
session_start();
|
||||
|
||||
// 1) Existing PHP session check (no regression)
|
||||
if(!empty($_SESSION["weval_auth"]) && $_SESSION["weval_auth"] === true) {
|
||||
http_response_code(200);
|
||||
echo "OK";
|
||||
} else {
|
||||
http_response_code(401);
|
||||
echo "UNAUTHORIZED";
|
||||
exit;
|
||||
}
|
||||
|
||||
// 2) NEW · Agent token bypass (header or query param)
|
||||
$supplied = $_SERVER["HTTP_X_AGENT_TOKEN"] ?? $_GET["_agent_token"] ?? "";
|
||||
|
||||
if ($supplied) {
|
||||
// Load expected from secrets.env
|
||||
$expected = "";
|
||||
if (is_readable("/etc/weval/secrets.env")) {
|
||||
foreach (file("/etc/weval/secrets.env", FILE_IGNORE_NEW_LINES) as $line) {
|
||||
if (strpos($line, "AGENT_TOKEN=") === 0) {
|
||||
$expected = trim(substr($line, strlen("AGENT_TOKEN=")));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fallback to DROID2026 (already trusted via /api/droid)
|
||||
if (!$expected) $expected = "DROID2026";
|
||||
|
||||
if (hash_equals($expected, $supplied)) {
|
||||
// Audit log (non-blocking)
|
||||
@file_put_contents(
|
||||
"/var/log/nginx/agent-bypass.log",
|
||||
date("c") . " " . ($_SERVER["HTTP_X_ORIGINAL_URI"] ?? "?") . " UA=" . ($_SERVER["HTTP_USER_AGENT"] ?? "?") . "\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
http_response_code(200);
|
||||
echo "AGENT-OK";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// 3) Unauthorized (default)
|
||||
http_response_code(401);
|
||||
echo "UNAUTHORIZED";
|
||||
|
||||
@@ -36,5 +36,17 @@
|
||||
"reason": "OVH credentials missing in /etc/weval/secrets.env. Add OVH_EMAIL + OVH_PASSWORD to enable automation.",
|
||||
"ts": "2026-04-21T10:00:02.008746",
|
||||
"status": "needs_credentials"
|
||||
},
|
||||
{
|
||||
"task": "ovh_s151_cancel",
|
||||
"reason": "OVH credentials missing in /etc/weval/secrets.env. Add OVH_EMAIL + OVH_PASSWORD to enable automation.",
|
||||
"ts": "2026-04-22T10:00:02.511432",
|
||||
"status": "needs_credentials"
|
||||
},
|
||||
{
|
||||
"task": "ovh_s151_cancel",
|
||||
"reason": "OVH credentials missing in /etc/weval/secrets.env. Add OVH_EMAIL + OVH_PASSWORD to enable automation.",
|
||||
"ts": "2026-04-23T10:00:02.909001",
|
||||
"status": "needs_credentials"
|
||||
}
|
||||
]
|
||||
@@ -1,140 +1,57 @@
|
||||
{
|
||||
"test": "biz-scenario-v9.29-extended",
|
||||
"timestamp": "2026-04-21T09-19-32",
|
||||
"test": "biz-scenario-v9.28",
|
||||
"timestamp": "2026-04-23T04-00-10",
|
||||
"pages": [
|
||||
{
|
||||
"name": "wtp",
|
||||
"url": "https://weval-consulting.com/weval-technology-platform.html?dev=1",
|
||||
"ok": true,
|
||||
"ms": 5929,
|
||||
"http": 200,
|
||||
"final_url": "https://weval-consulting.com/weval-technology-platform.html?dev=1",
|
||||
"ms": 21059,
|
||||
"found": [
|
||||
"WEVAL Technology",
|
||||
"NR ",
|
||||
"Archi complete",
|
||||
"Accueil",
|
||||
"NR "
|
||||
],
|
||||
"content_size": 337979
|
||||
"Accueil"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "erp-gap-fill",
|
||||
"url": "https://weval-consulting.com/erp-gap-fill-offer.html?dev=1",
|
||||
"ok": true,
|
||||
"ms": 3893,
|
||||
"http": 200,
|
||||
"final_url": "https://weval-consulting.com/erp-gap-fill-offer.html?dev=1",
|
||||
"ms": 4813,
|
||||
"found": [
|
||||
"CLOSED",
|
||||
"25",
|
||||
"Risk",
|
||||
"mitigation"
|
||||
],
|
||||
"content_size": 94849
|
||||
"CLOSED: 25"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "infra-tour",
|
||||
"url": "https://weval-consulting.com/infra-tour-2s-5c-blade.html?dev=1",
|
||||
"ok": true,
|
||||
"ms": 3226,
|
||||
"http": 200,
|
||||
"final_url": "https://weval-consulting.com/infra-tour-2s-5c-blade.html?dev=1",
|
||||
"ms": 3019,
|
||||
"found": [
|
||||
"S204",
|
||||
"S95",
|
||||
"Blade",
|
||||
"HTTPS"
|
||||
],
|
||||
"content_size": 9303
|
||||
"77%",
|
||||
"82%"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "wevia-master",
|
||||
"url": "https://weval-consulting.com/wevia-master.html?dev=1",
|
||||
"ok": true,
|
||||
"ms": 3862,
|
||||
"http": 200,
|
||||
"final_url": "https://weval-consulting.com/login?r=/wevia-master.html?dev=1",
|
||||
"ms": 16179,
|
||||
"found": [
|
||||
"master",
|
||||
"WEVIA"
|
||||
],
|
||||
"content_size": 3843
|
||||
},
|
||||
{
|
||||
"name": "ethica-hub",
|
||||
"url": "https://weval-consulting.com/ethica-hub.html?dev=1",
|
||||
"ok": true,
|
||||
"ms": 3959,
|
||||
"http": 200,
|
||||
"final_url": "https://weval-consulting.com/ethica-hub.html?dev=1",
|
||||
"found": [
|
||||
"Ethica",
|
||||
"HCP",
|
||||
"161",
|
||||
"51K"
|
||||
],
|
||||
"content_size": 32798
|
||||
},
|
||||
{
|
||||
"name": "enterprise-model",
|
||||
"url": "https://weval-consulting.com/enterprise-model.html?dev=1",
|
||||
"ok": true,
|
||||
"ms": 4372,
|
||||
"http": 200,
|
||||
"final_url": "https://weval-consulting.com/login?r=/enterprise-model.html?dev=1",
|
||||
"found": [
|
||||
"Enterprise",
|
||||
"agents"
|
||||
],
|
||||
"content_size": 3847
|
||||
},
|
||||
{
|
||||
"name": "growth-engine",
|
||||
"url": "https://weval-consulting.com/growth-engine-v2.html?dev=1",
|
||||
"ok": true,
|
||||
"ms": 5307,
|
||||
"http": 200,
|
||||
"final_url": "https://weval-consulting.com/login?r=/growth-engine-v2.html?dev=1",
|
||||
"found": [
|
||||
"Growth",
|
||||
"Engine",
|
||||
"growth",
|
||||
"engine",
|
||||
"html",
|
||||
"<body"
|
||||
],
|
||||
"content_size": 3847
|
||||
},
|
||||
{
|
||||
"name": "agents-archi",
|
||||
"url": "https://weval-consulting.com/agents-archi.html?dev=1",
|
||||
"ok": true,
|
||||
"ms": 9132,
|
||||
"http": 200,
|
||||
"final_url": "https://weval-consulting.com/login?r=/agents-archi.html?dev=1",
|
||||
"found": [
|
||||
"agents",
|
||||
"Architecture",
|
||||
"archi"
|
||||
],
|
||||
"content_size": 3843
|
||||
"master"
|
||||
]
|
||||
}
|
||||
],
|
||||
"video": "/var/www/html/videos/biz-scenario-2026-04-21T09-19-32.webm",
|
||||
"video": "/var/www/html/videos/biz-scenario-2026-04-23T04-00-10.webm",
|
||||
"screenshots": [
|
||||
"/var/www/html/screenshots/biz-2026-04-21T09-19-32-wtp.png",
|
||||
"/var/www/html/screenshots/biz-2026-04-21T09-19-32-erp-gap-fill.png",
|
||||
"/var/www/html/screenshots/biz-2026-04-21T09-19-32-infra-tour.png",
|
||||
"/var/www/html/screenshots/biz-2026-04-21T09-19-32-wevia-master.png",
|
||||
"/var/www/html/screenshots/biz-2026-04-21T09-19-32-ethica-hub.png",
|
||||
"/var/www/html/screenshots/biz-2026-04-21T09-19-32-enterprise-model.png",
|
||||
"/var/www/html/screenshots/biz-2026-04-21T09-19-32-growth-engine.png",
|
||||
"/var/www/html/screenshots/biz-2026-04-21T09-19-32-agents-archi.png"
|
||||
"/var/www/html/screenshots/biz-2026-04-23T04-00-10-wtp.png",
|
||||
"/var/www/html/screenshots/biz-2026-04-23T04-00-10-erp-gap-fill.png",
|
||||
"/var/www/html/screenshots/biz-2026-04-23T04-00-10-infra-tour.png",
|
||||
"/var/www/html/screenshots/biz-2026-04-23T04-00-10-wevia-master.png"
|
||||
],
|
||||
"duration_ms": 50075,
|
||||
"duration_ms": 55277,
|
||||
"status": "100%",
|
||||
"pass": 8,
|
||||
"total": 8,
|
||||
"pct": 100,
|
||||
"video_size": 1995296
|
||||
"pass": 4,
|
||||
"total": 4
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"generated_at": "2026-04-22T04:55:02.261221",
|
||||
"generated_at": "2026-04-23T19:45:02.216006",
|
||||
"stats": {
|
||||
"total": 48,
|
||||
"pending": 31,
|
||||
"total": 52,
|
||||
"pending": 33,
|
||||
"kaouther_surfaced": 18,
|
||||
"chrome_surfaced": 3,
|
||||
"chrome_surfaced": 5,
|
||||
"notif_only_done": 0,
|
||||
"autofix_archived": 0,
|
||||
"cerebras_archived": 0,
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"status": "ALIVE",
|
||||
"ts": "2026-04-22T04:45:01.644342",
|
||||
"last_heartbeat": "2026-04-22T04:45:01.644342",
|
||||
"last_heartbeat_ts_epoch": 1776825901,
|
||||
"tasks_today": 232,
|
||||
"tasks_week": 574,
|
||||
"agent_id": "blade-ops",
|
||||
"refreshed_by": "opus-v36-wire",
|
||||
"note": "V9.36 threshold 1800s + auto refresh hook"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user