2026-07-10 05:33:21 +00:00
import { expect , test } from "bun:test"
2026-07-27 00:08:55 +00:00
import { CodeModeTool } from "@opencode-ai/core/codemode/tool"
import { Tool } from "@opencode-ai/core/tool"
import { execute } from "@opencode-ai/core/tool/runtime"
2026-07-10 05:33:21 +00:00
import { Agent } from "@opencode-ai/schema/agent"
import { Session } from "@opencode-ai/schema/session"
import { SessionMessage } from "@opencode-ai/schema/session-message"
2026-07-27 00:08:55 +00:00
import type { Info } from "@opencode-ai/schema/tool"
import { Effect , Schema } from "effect"
2026-07-10 05:33:21 +00:00
2026-07-23 21:13:31 +00:00
const context = {
sessionID : Session.ID.make ( "ses_execute" ) ,
agent : Agent.ID.make ( "build" ) ,
messageID : SessionMessage.ID.make ( "msg_execute" ) ,
2026-07-27 00:08:55 +00:00
callID : Tool.CallID.make ( "call_execute" ) ,
2026-07-23 21:13:31 +00:00
progress : ( ) = > Effect . void ,
}
2026-07-27 00:08:55 +00:00
const createCodeMode = ( tools : ReadonlyMap < string , Info > ) = >
CodeModeTool . create ( tools , ( _ , tool , input , context ) = > execute ( tool , input , context ) )
2026-07-24 19:46:59 +00:00
test ( "execute describes invariant Code Mode behavior" , ( ) = > {
2026-07-27 00:08:55 +00:00
expect ( createCodeMode ( new Map ( ) ) . description ) . toBe (
2026-07-24 19:46:59 +00:00
[
2026-07-29 16:56:53 +00:00
"Run JavaScript in a confined Code Mode runtime to orchestrate tool calls and compose their results." ,
2026-07-24 19:46:59 +00:00
"Imports, direct filesystem access, and timers are unavailable. Do not use `fetch`; all external access goes through `tools`." ,
2026-07-25 01:49:55 +00:00
"Within `{ code }`, the only callable tools are those explicitly listed in the Code Mode catalog instructions or returned by `search`. Inside `{ code }`, ignore tools shown outside the Code Mode catalog. They are not available in the Code Mode runtime." ,
'Call tools through `tools` using only exact paths and signatures from the catalog. Do not infer or normalize tool names; preserve bracket notation such as `tools.<namespace>["tool-name"](input)`.' ,
2026-07-24 19:46:59 +00:00
"Prefer an explicit `return`; if omitted, the final top-level expression becomes the result." ,
"Await every call whose completion matters; pending calls are interrupted when execution ends. Run independent calls concurrently with `Promise.all`." ,
] . join ( "\n" ) ,
)
} )
2026-07-23 21:13:31 +00:00
test ( "canonical execution distinguishes declared, model-only, and raw schema outputs" , async ( ) = > {
2026-07-27 00:08:55 +00:00
const declared : Info = ( {
name : "declared" ,
2026-07-23 21:13:31 +00:00
description : "Declared" ,
input : Schema.Struct ( { value : Schema.String } ) ,
output : Schema.Struct ( { value : Schema.String } ) ,
execute : ( { value } ) = > Effect . succeed ( { output : { value } } ) ,
} )
2026-07-27 00:08:55 +00:00
const modelOnlyInput = Schema . Struct ( { } )
const modelOnly = ( {
name : "model_only" ,
2026-07-23 21:13:31 +00:00
description : "Model only" ,
2026-07-27 00:08:55 +00:00
input : modelOnlyInput ,
2026-07-23 21:13:31 +00:00
execute : ( ) = > Effect . succeed ( { content : "visible only" , metadata : { kind : "model" } } ) ,
2026-07-27 00:08:55 +00:00
} ) satisfies Info < typeof modelOnlyInput , undefined >
const raw : Info = ( {
name : "raw" ,
2026-07-23 21:13:31 +00:00
description : "Raw" ,
input : { } ,
output : { } ,
execute : ( input ) = > Effect . succeed ( { output : input , content : "raw" } ) ,
} )
2026-07-27 00:08:55 +00:00
expect ( await Effect . runPromise ( execute ( declared , { value : "encoded" } , context ) ) ) . toEqual ( {
2026-07-23 21:13:31 +00:00
output : { value : "encoded" } ,
content : [ { type : "text" , text : '{"value":"encoded"}' } ] ,
} )
2026-07-27 00:08:55 +00:00
expect ( await Effect . runPromise ( execute ( modelOnly , { } , context ) ) ) . toEqual ( {
output : undefined ,
2026-07-23 21:13:31 +00:00
content : [ { type : "text" , text : "visible only" } ] ,
metadata : { kind : "model" } ,
} )
2026-07-27 00:08:55 +00:00
expect ( await Effect . runPromise ( execute ( raw , { unchecked : true } , context ) ) ) . toEqual ( {
2026-07-23 21:13:31 +00:00
output : { unchecked : true } ,
content : [ { type : "text" , text : "raw" } ] ,
} )
} )
test ( "declared outputs cannot bypass validation and raw outputs stay JSON-compatible" , async ( ) = > {
2026-07-27 00:08:55 +00:00
const missing : Info = {
name : "missing" ,
2026-07-23 21:13:31 +00:00
description : "Missing output" ,
input : Schema.Struct ( { } ) ,
output : Schema.String ,
execute : ( ) = > Effect . succeed ( { content : "not an output" } ) ,
}
2026-07-27 00:08:55 +00:00
const invalid : Info = {
name : "invalid" ,
2026-07-23 21:13:31 +00:00
description : "Invalid raw output" ,
input : { } ,
output : { } ,
execute : ( ) = > Effect . succeed ( { output : 1n , content : "not JSON" } ) ,
}
2026-07-27 00:08:55 +00:00
expect ( ( await Effect . runPromiseExit ( execute ( missing , { } , context ) ) ) . toString ( ) ) . toContain (
2026-07-23 21:13:31 +00:00
"Tool did not return its declared output" ,
)
2026-07-27 00:08:55 +00:00
expect ( ( await Effect . runPromiseExit ( execute ( invalid , { } , context ) ) ) . toString ( ) ) . toContain (
2026-07-23 21:13:31 +00:00
"Tool returned a non-JSON value" ,
)
} )
2026-07-17 18:14:06 +00:00
test ( "execute supports callable namespace tools" , async ( ) = > {
2026-07-27 00:08:55 +00:00
const callable : Info = ( {
name : "admin" ,
2026-07-17 18:14:06 +00:00
description : "Administer Slack" ,
input : Schema.Struct ( { } ) ,
output : Schema.String ,
2026-07-27 00:08:55 +00:00
options : { namespace : "slack" } ,
2026-07-23 21:13:31 +00:00
execute : ( ) = > Effect . succeed ( { output : "admin" } ) ,
2026-07-17 18:14:06 +00:00
} )
2026-07-27 00:08:55 +00:00
const child : Info = ( {
name : "create" ,
2026-07-17 18:14:06 +00:00
description : "Create a Slack resource" ,
input : Schema.Struct ( { } ) ,
output : Schema.String ,
2026-07-27 00:08:55 +00:00
options : { namespace : "slack.admin" } ,
2026-07-23 21:13:31 +00:00
execute : ( ) = > Effect . succeed ( { output : "created" } ) ,
2026-07-17 18:14:06 +00:00
} )
2026-07-27 00:08:55 +00:00
const codeMode = createCodeMode (
2026-07-17 18:14:06 +00:00
new Map ( [
2026-07-27 00:08:55 +00:00
[ "slack_admin" , callable ] ,
[ "slack_admin_create" , child ] ,
2026-07-17 18:14:06 +00:00
] ) ,
)
const result = await Effect . runPromise (
2026-07-27 00:08:55 +00:00
codeMode . execute (
2026-07-23 21:13:31 +00:00
{ code : "return [await tools.slack.admin({}), await tools.slack.admin.create({})]" } ,
context ,
2026-07-17 18:14:06 +00:00
) ,
)
2026-07-23 21:13:31 +00:00
expect ( result . metadata ) . toEqual ( {
2026-07-17 18:14:06 +00:00
toolCalls : [
{ tool : "slack.admin" , status : "completed" } ,
{ tool : "slack.admin.create" , status : "completed" } ,
] ,
} )
expect ( result . content ) . toEqual ( [ { type : "text" , text : '[\n "admin",\n "created"\n]' } ] )
} )