@@ -55,11 +55,15 @@ import {
5555 makeSqlitePersistenceLive ,
5656 SqlitePersistenceMemory ,
5757} from "../../persistence/Layers/Sqlite.ts" ;
58+ import * as ServerConfig from "../../config.ts" ;
5859import * as ServerSettings from "../../serverSettings.ts" ;
5960import * as AnalyticsService from "../../telemetry/AnalyticsService.ts" ;
6061import { makeAdapterRegistryMock } from "../testUtils/providerAdapterRegistryMock.ts" ;
6162
6263const defaultServerSettingsLayer = ServerSettings . ServerSettingsService . layerTest ( ) ;
64+ const serverConfigTestLayer = ServerConfig . layerTest ( process . cwd ( ) , process . cwd ( ) ) . pipe (
65+ Layer . provide ( NodeServices . layer ) ,
66+ ) ;
6367
6468const asRequestId = ( value : string ) : ApprovalRequestId => ApprovalRequestId . make ( value ) ;
6569const asEventId = ( value : string ) : EventId => EventId . make ( value ) ;
@@ -292,6 +296,7 @@ function makeProviderServiceLayer() {
292296 Layer . provide ( providerAdapterLayer ) ,
293297 Layer . provide ( directoryLayer ) ,
294298 Layer . provide ( defaultServerSettingsLayer ) ,
299+ Layer . provide ( serverConfigTestLayer ) ,
295300 Layer . provideMerge ( AnalyticsService . layerTest ) ,
296301 Layer . provide (
297302 Layer . succeed (
@@ -343,6 +348,7 @@ it.effect("ProviderServiceLive catches stopAll failures during shutdown", () =>
343348 Layer . provide ( providerAdapterLayer ) ,
344349 Layer . provide ( directoryLayer ) ,
345350 Layer . provide ( defaultServerSettingsLayer ) ,
351+ Layer . provide ( serverConfigTestLayer ) ,
346352 Layer . provideMerge ( AnalyticsService . layerTest ) ,
347353 Layer . provide (
348354 Layer . succeed (
@@ -402,6 +408,7 @@ it.effect("ProviderServiceLive rejects new sessions for disabled providers", ()
402408 Layer . provide ( providerAdapterLayer ) ,
403409 Layer . provide ( directoryLayer ) ,
404410 Layer . provide ( defaultServerSettingsLayer ) ,
411+ Layer . provide ( serverConfigTestLayer ) ,
405412 Layer . provide ( AnalyticsService . layerTest ) ,
406413 Layer . provide (
407414 Layer . succeed (
@@ -486,6 +493,7 @@ it.effect(
486493 Layer . provide ( providerAdapterLayer ) ,
487494 Layer . provide ( directoryLayer ) ,
488495 Layer . provide ( serverSettingsLayer ) ,
496+ Layer . provide ( serverConfigTestLayer ) ,
489497 Layer . provide ( AnalyticsService . layerTest ) ,
490498 Layer . provide (
491499 Layer . succeed (
@@ -556,6 +564,7 @@ it.effect("ProviderServiceLive rejects new sessions for disabled custom instance
556564 Layer . provide ( providerAdapterLayer ) ,
557565 Layer . provide ( directoryLayer ) ,
558566 Layer . provide ( defaultServerSettingsLayer ) ,
567+ Layer . provide ( serverConfigTestLayer ) ,
559568 Layer . provide ( AnalyticsService . layerTest ) ,
560569 Layer . provide (
561570 Layer . succeed (
@@ -611,6 +620,7 @@ it.effect("ProviderServiceLive writes canonical events to the emitting thread se
611620 Layer . provide ( Layer . succeed ( ProviderAdapterRegistry . ProviderAdapterRegistry , registry ) ) ,
612621 Layer . provide ( directoryLayer ) ,
613622 Layer . provide ( defaultServerSettingsLayer ) ,
623+ Layer . provide ( serverConfigTestLayer ) ,
614624 Layer . provide ( AnalyticsService . layerTest ) ,
615625 Layer . provide (
616626 Layer . succeed (
@@ -671,6 +681,7 @@ it.effect("ProviderServiceLive keeps persisted resumable sessions on startup", (
671681 Layer . provide ( Layer . succeed ( ProviderAdapterRegistry . ProviderAdapterRegistry , registry ) ) ,
672682 Layer . provide ( directoryLayer ) ,
673683 Layer . provide ( defaultServerSettingsLayer ) ,
684+ Layer . provide ( serverConfigTestLayer ) ,
674685 Layer . provide ( AnalyticsService . layerTest ) ,
675686 Layer . provide (
676687 Layer . succeed (
@@ -737,6 +748,7 @@ it.effect(
737748 ) ,
738749 Layer . provide ( firstDirectoryLayer ) ,
739750 Layer . provide ( defaultServerSettingsLayer ) ,
751+ Layer . provide ( serverConfigTestLayer ) ,
740752 Layer . provide ( AnalyticsService . layerTest ) ,
741753 Layer . provide (
742754 Layer . succeed (
@@ -796,6 +808,7 @@ it.effect(
796808 ) ,
797809 Layer . provide ( secondDirectoryLayer ) ,
798810 Layer . provide ( defaultServerSettingsLayer ) ,
811+ Layer . provide ( serverConfigTestLayer ) ,
799812 Layer . provide ( AnalyticsService . layerTest ) ,
800813 Layer . provide (
801814 Layer . succeed (
@@ -927,6 +940,54 @@ routing.layer("ProviderServiceLive routing", (it) => {
927940 } ) ,
928941 ) ;
929942
943+ it . effect ( "appends attachment file paths to the turn input text" , ( ) =>
944+ Effect . gen ( function * ( ) {
945+ const provider = yield * ProviderService . ProviderService ;
946+
947+ const session = yield * provider . startSession ( asThreadId ( "thread-attach" ) , {
948+ provider : ProviderDriverKind . make ( "codex" ) ,
949+ providerInstanceId : codexInstanceId ,
950+ threadId : asThreadId ( "thread-attach" ) ,
951+ cwd : "/tmp/project" ,
952+ runtimeMode : "full-access" ,
953+ } ) ;
954+
955+ const attachment = {
956+ type : "image" as const ,
957+ id : "thread-attach-12345678-1234-1234-1234-123456789abc" ,
958+ name : "screenshot.png" ,
959+ mimeType : "image/png" ,
960+ sizeBytes : 123 ,
961+ } ;
962+
963+ routing . codex . sendTurn . mockClear ( ) ;
964+ yield * provider . sendTurn ( {
965+ threadId : session . threadId ,
966+ input : "use this screenshot" ,
967+ attachments : [ attachment ] ,
968+ } ) ;
969+
970+ const turnInput = routing . codex . sendTurn . mock . calls [ 0 ] ?. [ 0 ] as ProviderSendTurnInput ;
971+ assert . equal ( typeof turnInput . input , "string" ) ;
972+ const turnText = turnInput . input ?? "" ;
973+ assert . equal ( turnText . startsWith ( "use this screenshot" ) , true ) ;
974+ assert . include ( turnText , '[Attached image "screenshot.png" is saved at: ' ) ;
975+ assert . equal ( turnText . endsWith ( `${ attachment . id } .png]` ) , true ) ;
976+
977+ // An attachment-only turn stays valid and the injected line becomes the
978+ // whole input text, so the agent still learns the path.
979+ routing . codex . sendTurn . mockClear ( ) ;
980+ yield * provider . sendTurn ( {
981+ threadId : session . threadId ,
982+ attachments : [ attachment ] ,
983+ } ) ;
984+ const imageOnlyInput = routing . codex . sendTurn . mock . calls [ 0 ] ?. [ 0 ] as ProviderSendTurnInput ;
985+ assert . equal ( imageOnlyInput . input ?. startsWith ( '[Attached image "screenshot.png"' ) , true ) ;
986+
987+ yield * provider . stopSession ( { threadId : session . threadId } ) ;
988+ } ) ,
989+ ) ;
990+
930991 it . effect ( "recovers stale persisted sessions for rollback by resuming thread identity" , ( ) =>
931992 Effect . gen ( function * ( ) {
932993 const provider = yield * ProviderService . ProviderService ;
@@ -1307,6 +1368,7 @@ routing.layer("ProviderServiceLive routing", (it) => {
13071368 ) ,
13081369 Layer . provide ( firstDirectoryLayer ) ,
13091370 Layer . provide ( defaultServerSettingsLayer ) ,
1371+ Layer . provide ( serverConfigTestLayer ) ,
13101372 Layer . provide ( AnalyticsService . layerTest ) ,
13111373 Layer . provide (
13121374 Layer . succeed (
@@ -1345,6 +1407,7 @@ routing.layer("ProviderServiceLive routing", (it) => {
13451407 ) ,
13461408 Layer . provide ( secondDirectoryLayer ) ,
13471409 Layer . provide ( defaultServerSettingsLayer ) ,
1410+ Layer . provide ( serverConfigTestLayer ) ,
13481411 Layer . provide ( AnalyticsService . layerTest ) ,
13491412 Layer . provide (
13501413 Layer . succeed (
@@ -1413,6 +1476,7 @@ routing.layer("ProviderServiceLive routing", (it) => {
14131476 ) ,
14141477 Layer . provide ( firstDirectoryLayer ) ,
14151478 Layer . provide ( defaultServerSettingsLayer ) ,
1479+ Layer . provide ( serverConfigTestLayer ) ,
14161480 Layer . provide ( AnalyticsService . layerTest ) ,
14171481 Layer . provide (
14181482 Layer . succeed (
@@ -1446,6 +1510,7 @@ routing.layer("ProviderServiceLive routing", (it) => {
14461510 ) ,
14471511 Layer . provide ( secondDirectoryLayer ) ,
14481512 Layer . provide ( defaultServerSettingsLayer ) ,
1513+ Layer . provide ( serverConfigTestLayer ) ,
14491514 Layer . provide ( AnalyticsService . layerTest ) ,
14501515 Layer . provide (
14511516 Layer . succeed (
0 commit comments