ConusAI vendor v0.1.0-dev.20261027+9b1131fb
ci / gate (push) Waiting to run

This commit is contained in:
ConusAI vendor v0.1.0-dev.20261027+9b1131fb
2026-10-27 18:05:17 +00:00
commit 3102273ec7
538 changed files with 80203 additions and 0 deletions
+178
View File
@@ -0,0 +1,178 @@
// The agent module's adapters: the procedure handlers, the tools gateway over the registry client,
// the run job that drives the engine, and the subscriber that enqueues it.
import { AGENT_TOOLS, type AgentStep, dataRunStore, executeRun } from "@conusai-kit/agent"
import type { Container } from "@conusai-kit/core"
import { type EventContext, implement, internal, type JobDef, subscribe } from "@conusai-kit/core"
import { DATA_SOURCE, JOB_QUEUE } from "@conusai-kit/data"
import { createRegistryClient, type RegistryClient } from "@conusai-sdk/ai"
import { z } from "zod"
import {
approvalList,
approvalReview,
RUN_JOB,
runCancel,
runList,
runResumeRequested,
runStart,
runStatus,
} from "../contract/index.js"
import { AGENT_SCOPE, type AgentActionScope, type AgentDeps, type AgentScope } from "../core/ports.js"
import { cancelRun, getRun, listApprovals, listRuns, reviewApproval, startRun } from "../core/runs.js"
export function agentDeps(container: Container): AgentDeps {
return { data: container.resolve(DATA_SOURCE) }
}
export const runStartImpl = implement(runStart, ({ input, ctx }) =>
startRun(agentDeps(ctx.container), ctx.scope, {
goal: input.goal,
plan: input.plan,
...(input.budget === undefined ? {} : { budget: input.budget }),
}),
)
export const runStatusImpl = implement(runStatus, ({ input, ctx }) =>
getRun(agentDeps(ctx.container), ctx.scope, input.runId),
)
export const runCancelImpl = implement(runCancel, ({ input, ctx }) =>
cancelRun(agentDeps(ctx.container), ctx.scope, input.runId),
)
export const runListImpl = implement(runList, ({ input, ctx }) =>
listRuns(agentDeps(ctx.container), ctx.scope, {
...(input.cursor === undefined ? {} : { cursor: input.cursor }),
...(input.limit === undefined ? {} : { limit: input.limit }),
}),
)
export const approvalListImpl = implement(approvalList, ({ ctx }) => listApprovals(agentDeps(ctx.container), ctx.scope))
export const approvalReviewImpl = implement(approvalReview, ({ input, ctx }) =>
reviewApproval(agentDeps(ctx.container), ctx.scope, input),
)
export const AGENT_PROCEDURE_IMPLS = [
runStartImpl,
runStatusImpl,
runCancelImpl,
runListImpl,
approvalListImpl,
approvalReviewImpl,
]
// --- The tools gateway -----------------------------------------------------
/**
* The tools gateway over the organization's registry, with the app's scoped credentials. Each
* step's call carries the step's idempotency key, so a resumed step re-calls the same persisted
* action instead of creating a second one. When a write comes back `approval_required`, the exact
* stored proposed arguments are parked for a person; this adapter never approves.
*/
export function registryAgentTools(options: {
apiUrl: string
token: string
/** The organization's id the registry is addressed by. */
orgId: string
/** Fixed, or resolved per call: jobs of different tenants share the process binding. */
scope: AgentActionScope | (() => Promise<AgentActionScope>)
fetch?: typeof fetch
}): import("@conusai-kit/agent").AgentTools {
// Lazy: building the client validates the organization id, and a bare test container binds the
// tools without one until a call actually leaves the process.
let registry: RegistryClient | undefined
const client = (): RegistryClient => {
registry ??= createRegistryClient({
env: {
CONUSAI_API_URL: options.apiUrl,
CONUSAI_API_TOKEN: options.token,
CONUSAI_ORG_ID: options.orgId,
},
...(options.fetch === undefined ? {} : { fetch: options.fetch }),
})
return registry
}
const resolveScope =
typeof options.scope === "function" ? options.scope : () => Promise.resolve(options.scope as AgentActionScope)
return {
async call(name, args, callOptions) {
const result = await client().tools.call(name, args, { idempotencyKey: callOptions.idempotencyKey })
if (result.status === "completed") {
return {
status: "completed",
content: result.content,
// The registry call result does not carry metered usage yet (the metering slice owns
// that); steps and duration are tracked, and cost lands when the platform answers it.
usage: { costMicrocents: 0, steps: 1, tokens: 0 },
}
}
return {
status: "approval_required",
approval: {
actionId: result.request.actionId ?? null,
tool: name,
arguments: result.request.arguments,
reviewUrl: result.request.actionId
? client()
.tools.actions(await resolveScope())
.reviewUrl(result.request.actionId)
: null,
},
}
},
}
}
// --- The run job and its subscriber ----------------------------------------
const runPayload = z.object({ runId: z.string() })
type RunJobPayload = z.output<typeof runPayload>
export const runJob: JobDef<RunJobPayload> = {
payload: runPayload,
async handler(payload, ctx) {
const resolved = ctx.container.resolve(AGENT_SCOPE)
if (resolved.level !== "project")
throw internal(`an agent job runs in a project scope, not a ${resolved.level} one`)
const data = ctx.container.resolve(DATA_SOURCE)
const tools = ctx.container.resolve(AGENT_TOOLS)
const store = dataRunStore(data, resolved)
const record = await store.get(payload.runId)
if (!record) throw internal("the run this job belongs to is gone")
const plan: AgentStep[] = record.plan.map((planned) => ({
key: planned.key,
label: planned.label,
invoke: async (stepCtx) => {
const result = await tools.call(planned.tool, planned.args, {
signal: stepCtx.signal,
idempotencyKey: `${record.id}:${planned.key}`,
})
if (result.status === "completed") {
return {
ok: true as const,
usage: { costMicrocents: result.usage.costMicrocents, tokens: result.usage.tokens },
artifacts: [{ kind: "tool_result", ref: planned.tool }],
}
}
return { ok: false as const, awaitingApproval: result.approval }
},
}))
await executeRun({ store }, payload.runId, plan, { ...(ctx.signal === undefined ? {} : { signal: ctx.signal }) })
},
}
async function onRunResumeRequested(
event: { name: string; payload: { workspaceId: string; projectId: string; runId: string } },
ctx: EventContext,
): Promise<void> {
const ambient = ctx.container.resolve(AGENT_SCOPE)
if (ambient.level !== "project") throw internal("an agent event resolves to a project scope")
const scope: AgentScope = { ...ambient, workspaceId: event.payload.workspaceId, projectId: event.payload.projectId }
await ctx.container
.resolve(JOB_QUEUE)
.enqueue(scope, RUN_JOB, { runId: event.payload.runId }, { key: `agent.run.${event.payload.runId}` })
}
export const AGENT_JOBS = { [RUN_JOB]: runJob }
export const AGENT_SUBSCRIPTIONS = [subscribe(runResumeRequested, onRunResumeRequested)]