@@ -847,6 +847,8 @@ async function clientInvocation(
847847 ANTHROPIC_DEFAULT_OPUS_MODEL : model ,
848848 ANTHROPIC_DEFAULT_SONNET_MODEL : model ,
849849 ANTHROPIC_DEFAULT_HAIKU_MODEL : model ,
850+ ANTHROPIC_CUSTOM_MODEL_OPTION : model ,
851+ ANTHROPIC_CUSTOM_MODEL_OPTION_NAME : `FreeNIMAPI / ${ model } ` ,
850852 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC : "1" ,
851853 CLAUDE_TMPDIR : path . join ( runRoot , "tmp" ) ,
852854 CLAUDE_CODE_TMPDIR : path . join ( runRoot , "tmp" ) ,
@@ -963,9 +965,18 @@ async function startProxy(model) {
963965 `live-nvidia-nim requires ${ OFFICIAL_NVIDIA_UPSTREAM_ORIGIN } ; got ${ upstreamOrigin } ` ,
964966 ) ;
965967 }
968+ const logCounts = { warn : 0 , error : 0 } ;
966969 const server = createFreeNimServer ( {
967970 config,
968- logger : { info ( ) { } , warn ( ) { } , error ( ) { } } ,
971+ logger : {
972+ info ( ) { } ,
973+ warn ( ) {
974+ logCounts . warn += 1 ;
975+ } ,
976+ error ( ) {
977+ logCounts . error += 1 ;
978+ } ,
979+ } ,
969980 } ) ;
970981 await new Promise ( ( resolve , reject ) => {
971982 server . once ( "error" , reject ) ;
@@ -975,6 +986,65 @@ async function startProxy(model) {
975986 server,
976987 baseUrl : `http://127.0.0.1:${ server . address ( ) . port } ` ,
977988 upstreamOrigin,
989+ logCounts,
990+ } ;
991+ }
992+
993+ async function startupCompatibilityPreflight ( baseUrl , model ) {
994+ const headers = { authorization : `Bearer ${ LOCAL_KEY } ` } ;
995+ const optionalProbePaths = [
996+ "/api/v1/models" ,
997+ "/api/tags" ,
998+ "/v1/props" ,
999+ "/props" ,
1000+ "/version" ,
1001+ ] ;
1002+ const optionalProbes = { } ;
1003+
1004+ for ( const probePath of optionalProbePaths ) {
1005+ const response = await fetch ( `${ baseUrl } ${ probePath } ` , { headers } ) ;
1006+ optionalProbes [ probePath ] = response . status ;
1007+ await response . text ( ) ;
1008+ if ( response . status !== 404 ) {
1009+ throw new Error (
1010+ `Local-server discovery probe ${ probePath } must return a truthful HTTP 404; got ${ response . status } ` ,
1011+ ) ;
1012+ }
1013+ }
1014+
1015+ const listResponse = await fetch ( `${ baseUrl } /v1/models` , { headers } ) ;
1016+ if ( ! listResponse . ok ) {
1017+ throw new Error ( `Model catalog preflight failed with HTTP ${ listResponse . status } ` ) ;
1018+ }
1019+ const catalog = await listResponse . json ( ) ;
1020+ if ( catalog ?. object !== "list" || ! Array . isArray ( catalog ?. data ) ) {
1021+ throw new Error ( "Model catalog preflight returned an invalid OpenAI-compatible payload" ) ;
1022+ }
1023+
1024+ const detailResponse = await fetch (
1025+ `${ baseUrl } /v1/models/${ encodeURIComponent ( model ) } ` ,
1026+ { headers } ,
1027+ ) ;
1028+ if ( ! detailResponse . ok ) {
1029+ throw new Error (
1030+ `Hermes model metadata preflight for '${ model } ' failed with HTTP ${ detailResponse . status } ` ,
1031+ ) ;
1032+ }
1033+ const detail = await detailResponse . json ( ) ;
1034+ if ( detail ?. object !== "model" || typeof detail ?. id !== "string" ) {
1035+ throw new Error ( "Hermes model metadata preflight returned an invalid model object" ) ;
1036+ }
1037+ if ( ! catalog . data . some ( ( entry ) => entry ?. id === detail . id ) ) {
1038+ throw new Error ( `Retrieved model '${ detail . id } ' is missing from the model catalog` ) ;
1039+ }
1040+
1041+ return {
1042+ passed : true ,
1043+ model_requested : model ,
1044+ model_resolved : detail . id ,
1045+ list_status : listResponse . status ,
1046+ detail_status : detailResponse . status ,
1047+ optional_probe_statuses : optionalProbes ,
9781048 } ;
9791049}
9801050
@@ -1317,6 +1387,8 @@ function markdownReport(report) {
13171387 "Run the normal Hermes E2E separately for completed-tool ordering evidence." ,
13181388 "" ,
13191389 `- Hermes process: ${ mark ( result ?. checks ?. client_exit ) } ` ,
1390+ `- Hermes startup compatibility: ${ mark ( report . startup_compatibility ?. passed ) } ` ,
1391+ `- Clean proxy log: ${ report . proxy_logs ?. observable ? mark ( report . proxy_logs . clean ) : "NOT OBSERVABLE" } ` ,
13201392 `- Initial fixture RED: ${ mark ( result ?. checks ?. initial_fixture_red ) } ` ,
13211393 `- Production source changed: ${ mark ( result ?. checks ?. source_changed ) } ` ,
13221394 `- Contract protected: ${ mark ( result ?. checks ?. contract_unchanged ) } ` ,
@@ -1338,6 +1410,8 @@ function markdownReport(report) {
13381410 `- Text tool fallback: disabled` ,
13391411 `- Structural tool preflight: ${ report . preflight . structural_tool_call ? "PASS" : "FAIL" } ` ,
13401412 `- Tool continuation preflight: ${ report . preflight . tool_continuation ? "PASS" : "FAIL" } ` ,
1413+ `- Hermes startup compatibility: ${ report . startup_compatibility ?. passed ? "PASS" : "FAIL" } ` ,
1414+ `- Clean proxy log: ${ report . proxy_logs ?. observable ? ( report . proxy_logs . clean ? "PASS" : "FAIL" ) : "NOT OBSERVABLE" } ` ,
13411415 "" ,
13421416 "| Client | Result | Initial RED | Failure→edit→green | Source changed | Contract protected | Independent tests | Final turn |" ,
13431417 "|---|---:|---:|---:|---:|---:|---:|---:|" ,
@@ -1371,6 +1445,7 @@ async function main() {
13711445 requireLoopbackProxy ( baseUrl ) ;
13721446
13731447 try {
1448+ const startupCompatibility = await startupCompatibilityPreflight ( baseUrl , options . model ) ;
13741449 const preflight = await livePreflight (
13751450 baseUrl ,
13761451 options . model ,
@@ -1409,6 +1484,19 @@ async function main() {
14091484 }
14101485 }
14111486
1487+ const proxyLogs = ownedProxy
1488+ ? {
1489+ observable : true ,
1490+ warn_count : ownedProxy . logCounts . warn ,
1491+ error_count : ownedProxy . logCounts . error ,
1492+ clean : ownedProxy . logCounts . warn === 0 && ownedProxy . logCounts . error === 0 ,
1493+ }
1494+ : {
1495+ observable : false ,
1496+ warn_count : null ,
1497+ error_count : null ,
1498+ clean : null ,
1499+ } ;
14121500 const report = {
14131501 timestamp : new Date ( ) . toISOString ( ) ,
14141502 mode : options . hermesCliDemo ? "visual-hermes-cli-demo" : options . mode ,
@@ -1417,9 +1505,15 @@ async function main() {
14171505 proxy_ownership : ownedProxy ? "runner-owned" : "external-unverified" ,
14181506 upstream_provider : ownedProxy ? "nvidia-nim" : "unverified" ,
14191507 upstream_origin : ownedProxy ?. upstreamOrigin ?? null ,
1508+ startup_compatibility : startupCompatibility ,
1509+ proxy_logs : proxyLogs ,
14201510 preflight,
14211511 results,
1422- passed : results . length > 0 && results . every ( ( result ) => result . passed ) ,
1512+ passed :
1513+ startupCompatibility . passed &&
1514+ ( ! proxyLogs . observable || proxyLogs . clean ) &&
1515+ results . length > 0 &&
1516+ results . every ( ( result ) => result . passed ) ,
14231517 } ;
14241518 await writeFile ( path . join ( reportDir , "report.json" ) , `${ JSON . stringify ( report , null , 2 ) } \n` ) ;
14251519 await writeFile ( path . join ( reportDir , "SUMMARY.md" ) , markdownReport ( report ) ) ;
0 commit comments