feat(aircoding): AirCoding V2 baseline — deterministic multi-agent architecture
Forked from OpenCode v1.17.4 with multi-agent system: - 5 agents: aircoding, scheduler, worker, architect, reviewer - Deterministic DAG scheduling engine (coordinator_tick) - Tool whitelists as hard enforcement - AirCoding validation plugin - V1 requirements: C4 docs, ADR, AGENTS.md, debug-log.md - Design documents in docs/
This commit is contained in:
86
packages/opencode/test/session/system.test.ts
Normal file
86
packages/opencode/test/session/system.test.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import { describe, expect } from "bun:test"
|
||||
import { Effect, Layer } from "effect"
|
||||
import type { Agent } from "../../src/agent/agent"
|
||||
import { NamedError } from "@opencode-ai/core/util/error"
|
||||
import { Skill } from "../../src/skill"
|
||||
import { Permission } from "../../src/permission"
|
||||
import { SystemPrompt } from "../../src/session/system"
|
||||
import { LocationServiceMap } from "@opencode-ai/core/location-layer"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const skills: Skill.Info[] = [
|
||||
{
|
||||
name: "zeta-skill",
|
||||
description: "Zeta skill.",
|
||||
location: "/tmp/zeta-skill/SKILL.md",
|
||||
content: "# zeta-skill",
|
||||
},
|
||||
{
|
||||
name: "alpha-skill",
|
||||
description: "Alpha skill.",
|
||||
location: "/tmp/alpha-skill/SKILL.md",
|
||||
content: "# alpha-skill",
|
||||
},
|
||||
{
|
||||
name: "middle-skill",
|
||||
description: "Middle skill.",
|
||||
location: "/tmp/middle-skill/SKILL.md",
|
||||
content: "# middle-skill",
|
||||
},
|
||||
{
|
||||
name: "manual-skill",
|
||||
location: "/tmp/manual-skill/SKILL.md",
|
||||
content: "# manual-skill",
|
||||
},
|
||||
]
|
||||
|
||||
const build: Agent.Info = {
|
||||
name: "build",
|
||||
mode: "primary",
|
||||
permission: Permission.fromConfig({ "*": "allow" }),
|
||||
options: {},
|
||||
}
|
||||
|
||||
const it = testEffect(
|
||||
SystemPrompt.layer.pipe(
|
||||
Layer.provide(LocationServiceMap.layer),
|
||||
Layer.provide(
|
||||
Layer.succeed(
|
||||
Skill.Service,
|
||||
Skill.Service.of({
|
||||
get: (name) => Effect.succeed(skills.find((skill) => skill.name === name)),
|
||||
require: (name) => {
|
||||
const info = skills.find((skill) => skill.name === name)
|
||||
if (info) return Effect.succeed(info)
|
||||
return Effect.fail(new Skill.NotFoundError({ name, available: skills.map((skill) => skill.name) }))
|
||||
},
|
||||
all: () => Effect.succeed(skills),
|
||||
dirs: () => Effect.succeed([]),
|
||||
available: () => Effect.succeed(skills),
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
describe("session.system", () => {
|
||||
it.effect("skills output is sorted by name and stable across calls", () =>
|
||||
Effect.gen(function* () {
|
||||
const prompt = yield* SystemPrompt.Service
|
||||
const first = yield* prompt.skills(build)
|
||||
const second = yield* prompt.skills(build)
|
||||
const output = first ?? (yield* Effect.fail(new NamedError.Unknown({ message: "missing skills output" })))
|
||||
|
||||
expect(first).toBe(second)
|
||||
|
||||
const alpha = output.indexOf("<name>alpha-skill</name>")
|
||||
const middle = output.indexOf("<name>middle-skill</name>")
|
||||
const zeta = output.indexOf("<name>zeta-skill</name>")
|
||||
|
||||
expect(alpha).toBeGreaterThan(-1)
|
||||
expect(middle).toBeGreaterThan(alpha)
|
||||
expect(zeta).toBeGreaterThan(middle)
|
||||
expect(output).not.toContain("manual-skill")
|
||||
}),
|
||||
)
|
||||
})
|
||||
Reference in New Issue
Block a user