feat(agnet): SK repo_ref validation, create deployment UI, docs touch-ups
Extend agnet SK sources with repo_ref and snapshot display; add authenticated deployment sheet + API types; cockpit toolbar entry; locale strings; minor docs. Made-with: Cursor
This commit is contained in:
@@ -124,6 +124,10 @@ Tenant(租户)
|
||||
|
||||
下列条款为 **Heicode 与 Agnet 联合落地时必须写清** 的契约;API 形状可与 `**POST /deployments`** 合一或拆为 `**POST /teams/deployments`** 等聚合端点,但 **语义不得缩水**。
|
||||
|
||||
**启动参数与权限归属(与 Manager 的边界)**
|
||||
|
||||
- **Agnet 在拉起编队 / 子 agent 运行时**(进程或等价隔离单元)须获得完整部署参数:`sk_sources`、`runtime_execution`、`sk_access_policy`、成员与模型声明等;**不得在缺少参数时静默放宽为越权默认**。
|
||||
- **权限与策略的可执行副本落在 Agnet**:Git 连接、`cloud_principal_refs`、SK 允许/拒绝边界由 Agnet 控制面 **落账并在运行时强制执行**;Heicode Manager **只负责发起部署请求并展示 Agnet 回传的快照锚点与观测字段**,**不是**运行时的权限裁决引擎。
|
||||
|
||||
| 契约项 | 要求 |
|
||||
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
|
||||
@@ -120,8 +120,7 @@ Agnet 不需要、也不应该提供针对 SK 正文的 `PUT` / `PATCH`:写操
|
||||
- 团队成员列表与组织内角色
|
||||
- 各成员所用模型 / `provider_profile_id`
|
||||
- 子 agent 模板与 `sk_sources`
|
||||
- **用户在 Manager 配置的子 agent 云上 / 运行时权限**(如 `runtime_execution`:VM 池、云 principal、网络策略等),**必须随部署请求传给 Agnet**,不得在链路中丢弃
|
||||
- **SK 允许 / 禁止策略**(如 `sk_access_policy`),与快照合并后的生效边界须由平台落账,子 agent 仅能在该边界内消费 SK
|
||||
- **子 agent 云上 / 运行时权限等参数**(如 `runtime_execution`)与 **SK 允许 / 禁止策略**(如 `sk_access_policy`)须 **在 Agnet 拉起编队/运行时随部署请求传入**;**生效副本落在 Agnet**,由其运行时强制执行;Manager 仅透传配置并展示回传锚点,不作执行时代替
|
||||
|
||||
部署完成后 Manager 应能展示:
|
||||
|
||||
|
||||
@@ -22,9 +22,19 @@ type agnetBudget struct {
|
||||
MaxDurationSec int `json:"max_duration_sec"`
|
||||
}
|
||||
|
||||
// agnetRepoRef matches docs/integration/orchestration-plan-contract.md (git sk_sources).
|
||||
type agnetRepoRef struct {
|
||||
ConnectionID string `json:"connection_id"`
|
||||
RepoURL string `json:"repo_url"`
|
||||
Ref string `json:"ref"`
|
||||
Paths []string `json:"paths"`
|
||||
}
|
||||
|
||||
type agnetSKSource struct {
|
||||
Type string `json:"type"`
|
||||
ArtifactID string `json:"artifact_id"`
|
||||
Type string `json:"type"`
|
||||
ArtifactID string `json:"artifact_id"`
|
||||
Mime string `json:"mime"`
|
||||
RepoRef agnetRepoRef `json:"repo_ref"`
|
||||
}
|
||||
|
||||
// agnetRuntimeExecution mirrors docs/integration/agnet-platform-api-design.md §5.0 (runtime_execution).
|
||||
@@ -166,6 +176,58 @@ func validateAgentRuntimeBindings(c *gin.Context, agent agnetAgentPlan) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func skSourceDisplayRef(s agnetSKSource) string {
|
||||
switch strings.TrimSpace(s.Type) {
|
||||
case "git":
|
||||
r := s.RepoRef
|
||||
ref := strings.TrimSpace(r.Ref)
|
||||
pathPart := strings.Join(r.Paths, ",")
|
||||
if ref != "" && pathPart != "" {
|
||||
return ref + ":" + pathPart
|
||||
}
|
||||
if ref != "" {
|
||||
return ref
|
||||
}
|
||||
return "git"
|
||||
case "upload":
|
||||
id := strings.TrimSpace(s.ArtifactID)
|
||||
if id != "" {
|
||||
return id
|
||||
}
|
||||
return "upload"
|
||||
default:
|
||||
return strings.TrimSpace(s.ArtifactID)
|
||||
}
|
||||
}
|
||||
|
||||
func validateSKSourceEntry(c *gin.Context, source agnetSKSource) bool {
|
||||
sourceType := strings.TrimSpace(source.Type)
|
||||
if sourceType == "" {
|
||||
return true
|
||||
}
|
||||
switch sourceType {
|
||||
case "git":
|
||||
ref := source.RepoRef
|
||||
if strings.TrimSpace(ref.Ref) == "" {
|
||||
agnetError(c, "SK_SOURCE_UNRESOLVABLE", "git sk_sources.repo_ref.ref is required")
|
||||
return false
|
||||
}
|
||||
if len(ref.Paths) == 0 {
|
||||
agnetError(c, "SK_SOURCE_UNRESOLVABLE", "git sk_sources.repo_ref.paths must not be empty")
|
||||
return false
|
||||
}
|
||||
case "upload":
|
||||
if strings.TrimSpace(source.ArtifactID) == "" {
|
||||
agnetError(c, "SK_SOURCE_UNRESOLVABLE", "upload sk_sources.artifact_id is required")
|
||||
return false
|
||||
}
|
||||
default:
|
||||
agnetError(c, "SK_SOURCE_UNRESOLVABLE", "unsupported sk source type")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func validateAgentSKAccessPolicy(c *gin.Context, agent agnetAgentPlan) bool {
|
||||
p := agent.SKAccessPolicy
|
||||
hasDeny := len(p.DenySkillIDs) > 0
|
||||
@@ -223,9 +285,7 @@ func validateOrchestrationPlan(c *gin.Context, plan agnetOrchestrationPlan) bool
|
||||
return false
|
||||
}
|
||||
for _, source := range agent.SKSources {
|
||||
sourceType := strings.TrimSpace(source.Type)
|
||||
if sourceType != "" && sourceType != "git" && sourceType != "upload" {
|
||||
agnetError(c, "SK_SOURCE_UNRESOLVABLE", "unsupported sk source type")
|
||||
if !validateSKSourceEntry(c, source) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -449,10 +509,13 @@ func AgnetResolveSKSnapshots(c *gin.Context) {
|
||||
if sourceType == "" {
|
||||
continue
|
||||
}
|
||||
sourceRef := strings.TrimSpace(source.ArtifactID)
|
||||
if sourceRef == "" {
|
||||
sourceRef := skSourceDisplayRef(source)
|
||||
if strings.TrimSpace(sourceRef) == "" {
|
||||
sourceRef = "ref_" + common.GetUUID()[:8]
|
||||
}
|
||||
if sourceType == "git" {
|
||||
sourceRef = sourceRef + "@sha_" + common.GetUUID()[:12]
|
||||
}
|
||||
snapshots = append(snapshots, agnetSKSnapshot{
|
||||
SnapshotID: "sks_" + common.GetUUID()[:12],
|
||||
DeploymentID: deploymentID,
|
||||
|
||||
+86
-13
@@ -14,6 +14,68 @@ export type AgnetSKAccessPolicy = {
|
||||
inherit_deployment_defaults?: boolean
|
||||
}
|
||||
|
||||
/** Git-backed SK source (`type: git`). */
|
||||
export type AgnetRepoRef = {
|
||||
connection_id?: string
|
||||
repo_url?: string
|
||||
ref: string
|
||||
paths: string[]
|
||||
}
|
||||
|
||||
/** Single SK source entry (git or upload). */
|
||||
export type AgnetSKSource = {
|
||||
type?: string
|
||||
artifact_id?: string
|
||||
mime?: string
|
||||
repo_ref?: AgnetRepoRef
|
||||
}
|
||||
|
||||
export type AgnetAgentPlan = {
|
||||
role_template: string
|
||||
goal: string
|
||||
default_model_id?: string
|
||||
sk_sources?: AgnetSKSource[]
|
||||
runtime_execution?: AgnetRuntimeExecution
|
||||
sk_access_policy?: AgnetSKAccessPolicy
|
||||
}
|
||||
|
||||
export type AgnetBudget = {
|
||||
max_tokens: number
|
||||
max_cost_usd: number
|
||||
max_duration_sec: number
|
||||
}
|
||||
|
||||
export type AgnetConstraints = {
|
||||
allowed_model_ids?: string[]
|
||||
}
|
||||
|
||||
export type AgnetOrchestrationMetadata = {
|
||||
tenant_id: string
|
||||
project_id: string
|
||||
correlation_id: string
|
||||
}
|
||||
|
||||
export type AgnetOrchestrationPlan = {
|
||||
intent_id: string
|
||||
template_hint: string
|
||||
objective: string
|
||||
risk_level: 'low' | 'medium' | 'high'
|
||||
budget: AgnetBudget
|
||||
agents: AgnetAgentPlan[]
|
||||
constraints: AgnetConstraints
|
||||
metadata: AgnetOrchestrationMetadata
|
||||
}
|
||||
|
||||
export type AgnetCreateDeploymentBody = {
|
||||
orchestration_plan: AgnetOrchestrationPlan
|
||||
}
|
||||
|
||||
export type AgnetCreateDeploymentResult = {
|
||||
deployment_id: string
|
||||
status: string
|
||||
agent_instances?: Array<{ instance_id?: string; role?: string; phase?: string }>
|
||||
}
|
||||
|
||||
export type AgnetDeployment = {
|
||||
deployment_id: string
|
||||
status: string
|
||||
@@ -21,21 +83,14 @@ export type AgnetDeployment = {
|
||||
created_at: string
|
||||
updated_at: string
|
||||
orchestration_plan: {
|
||||
intent_id?: string
|
||||
template_hint?: string
|
||||
objective?: string
|
||||
agents?: Array<{
|
||||
role_template?: string
|
||||
goal?: string
|
||||
default_model_id?: string
|
||||
sk_sources?: Array<{ type?: string; artifact_id?: string }>
|
||||
runtime_execution?: AgnetRuntimeExecution
|
||||
sk_access_policy?: AgnetSKAccessPolicy
|
||||
}>
|
||||
metadata?: {
|
||||
tenant_id?: string
|
||||
project_id?: string
|
||||
correlation_id?: string
|
||||
}
|
||||
risk_level?: string
|
||||
budget?: AgnetBudget
|
||||
agents?: AgnetAgentPlan[]
|
||||
constraints?: AgnetConstraints
|
||||
metadata?: AgnetOrchestrationMetadata
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +103,24 @@ export async function listAgnetDeployments(): Promise<AgnetDeployment[]> {
|
||||
return res.data?.data?.items ?? []
|
||||
}
|
||||
|
||||
export async function createAgnetDeployment(
|
||||
body: AgnetCreateDeploymentBody
|
||||
): Promise<AgnetCreateDeploymentResult> {
|
||||
const res = await api.post<ApiEnvelope<AgnetCreateDeploymentResult>>(
|
||||
'/api/agnet/deployments',
|
||||
body
|
||||
)
|
||||
const env = res.data
|
||||
if (!env?.success) {
|
||||
throw new Error(env?.message || 'Deployment request failed')
|
||||
}
|
||||
const data = env.data
|
||||
if (!data?.deployment_id) {
|
||||
throw new Error(env?.message || 'Invalid deployment response')
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
export async function getAgnetDeploymentEvents(deploymentId: string) {
|
||||
const res = await api.get<ApiEnvelope<{ items?: Array<Record<string, unknown>> }>>(
|
||||
`/api/agnet/deployments/${deploymentId}/events`
|
||||
|
||||
+626
@@ -0,0 +1,626 @@
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { toast } from 'sonner'
|
||||
import { Loader2, Plus, Trash2 } from 'lucide-react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import {
|
||||
Sheet,
|
||||
SheetContent,
|
||||
SheetDescription,
|
||||
SheetFooter,
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
} from '@/components/ui/sheet'
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/components/ui/select'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import {
|
||||
createAgnetDeployment,
|
||||
type AgnetAgentPlan,
|
||||
type AgnetOrchestrationPlan,
|
||||
type AgnetSKSource,
|
||||
} from './api'
|
||||
|
||||
type AgentFormRow = {
|
||||
role_template: string
|
||||
goal: string
|
||||
default_model_id: string
|
||||
sk_sources_json: string
|
||||
profile_id: string
|
||||
cloud_principals: string
|
||||
network_policy_ref: string
|
||||
policy_ref: string
|
||||
deny_skill_ids: string
|
||||
inherit_defaults: boolean
|
||||
}
|
||||
|
||||
function splitComma(s: string): string[] {
|
||||
return s
|
||||
.split(',')
|
||||
.map((x) => x.trim())
|
||||
.filter(Boolean)
|
||||
}
|
||||
|
||||
function buildAgent(row: AgentFormRow): AgnetAgentPlan {
|
||||
let sk_sources: AgnetSKSource[] | undefined
|
||||
const raw = row.sk_sources_json.trim()
|
||||
if (raw) {
|
||||
const parsed = JSON.parse(raw) as unknown
|
||||
if (!Array.isArray(parsed)) {
|
||||
throw new Error('sk_sources_must_be_array')
|
||||
}
|
||||
sk_sources = parsed as AgnetSKSource[]
|
||||
}
|
||||
|
||||
const profileId = row.profile_id.trim()
|
||||
const net = row.network_policy_ref.trim()
|
||||
const clouds = splitComma(row.cloud_principals)
|
||||
const hasRuntime =
|
||||
profileId !== '' || net !== '' || clouds.length > 0
|
||||
if (hasRuntime && profileId === '') {
|
||||
throw new Error('profile_required_for_runtime')
|
||||
}
|
||||
|
||||
const deny = splitComma(row.deny_skill_ids)
|
||||
const pref = row.policy_ref.trim()
|
||||
|
||||
const runtime =
|
||||
profileId || net || clouds.length > 0
|
||||
? {
|
||||
profile_id: profileId,
|
||||
cloud_principal_refs: clouds.length > 0 ? clouds : undefined,
|
||||
network_policy_ref: net || undefined,
|
||||
}
|
||||
: undefined
|
||||
|
||||
const skPolicy =
|
||||
pref || deny.length > 0 || row.inherit_defaults
|
||||
? {
|
||||
policy_ref: pref || undefined,
|
||||
deny_skill_ids: deny.length > 0 ? deny : undefined,
|
||||
inherit_deployment_defaults: row.inherit_defaults,
|
||||
}
|
||||
: undefined
|
||||
|
||||
return {
|
||||
role_template: row.role_template.trim(),
|
||||
goal: row.goal.trim(),
|
||||
default_model_id: row.default_model_id.trim() || undefined,
|
||||
sk_sources,
|
||||
runtime_execution: runtime,
|
||||
sk_access_policy: skPolicy,
|
||||
}
|
||||
}
|
||||
|
||||
const DEFAULT_SK_JSON = `[
|
||||
{
|
||||
"type": "git",
|
||||
"repo_ref": {
|
||||
"connection_id": "",
|
||||
"repo_url": "",
|
||||
"ref": "main",
|
||||
"paths": ["policy/sk.md"]
|
||||
}
|
||||
}
|
||||
]`
|
||||
|
||||
const emptyAgent = (): AgentFormRow => ({
|
||||
role_template: '',
|
||||
goal: '',
|
||||
default_model_id: '',
|
||||
sk_sources_json: '[]',
|
||||
profile_id: '',
|
||||
cloud_principals: '',
|
||||
network_policy_ref: '',
|
||||
policy_ref: '',
|
||||
deny_skill_ids: '',
|
||||
inherit_defaults: true,
|
||||
})
|
||||
|
||||
export function CreateAgnetDeploymentSheet({
|
||||
open,
|
||||
onOpenChange,
|
||||
}: {
|
||||
open: boolean
|
||||
onOpenChange: (open: boolean) => void
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const [templateHint, setTemplateHint] = useState('agile_min')
|
||||
const [objective, setObjective] = useState('')
|
||||
const [riskLevel, setRiskLevel] = useState<'low' | 'medium' | 'high'>(
|
||||
'medium'
|
||||
)
|
||||
const [maxTokens, setMaxTokens] = useState(120_000)
|
||||
const [maxCost, setMaxCost] = useState(8)
|
||||
const [maxDurationSec, setMaxDurationSec] = useState(3600)
|
||||
const [tenantId, setTenantId] = useState('ten_local')
|
||||
const [projectId, setProjectId] = useState('prj_default')
|
||||
const [correlationId, setCorrelationId] = useState('')
|
||||
const [allowedModels, setAllowedModels] = useState('')
|
||||
const [agents, setAgents] = useState<AgentFormRow[]>([emptyAgent()])
|
||||
|
||||
useEffect(() => {
|
||||
if (open && !correlationId) {
|
||||
setCorrelationId(crypto.randomUUID())
|
||||
}
|
||||
}, [open, correlationId])
|
||||
|
||||
const resetForm = () => {
|
||||
setTemplateHint('agile_min')
|
||||
setObjective('')
|
||||
setRiskLevel('medium')
|
||||
setMaxTokens(120_000)
|
||||
setMaxCost(8)
|
||||
setMaxDurationSec(3600)
|
||||
setTenantId('ten_local')
|
||||
setProjectId('prj_default')
|
||||
setCorrelationId(crypto.randomUUID())
|
||||
setAllowedModels('')
|
||||
setAgents([emptyAgent()])
|
||||
}
|
||||
|
||||
const mutation = useMutation({
|
||||
mutationFn: async () => {
|
||||
const intentId = crypto.randomUUID()
|
||||
const allowed = splitComma(allowedModels)
|
||||
let agentPlans: AgnetAgentPlan[]
|
||||
try {
|
||||
agentPlans = agents.map((row) => buildAgent(row))
|
||||
} catch (e) {
|
||||
if (e instanceof SyntaxError) {
|
||||
throw new Error('invalid_sk_sources_json')
|
||||
}
|
||||
throw e
|
||||
}
|
||||
|
||||
const plan: AgnetOrchestrationPlan = {
|
||||
intent_id: intentId,
|
||||
template_hint: templateHint.trim(),
|
||||
objective: objective.trim(),
|
||||
risk_level: riskLevel,
|
||||
budget: {
|
||||
max_tokens: maxTokens,
|
||||
max_cost_usd: maxCost,
|
||||
max_duration_sec: maxDurationSec,
|
||||
},
|
||||
agents: agentPlans,
|
||||
constraints: {
|
||||
allowed_model_ids: allowed.length > 0 ? allowed : undefined,
|
||||
},
|
||||
metadata: {
|
||||
tenant_id: tenantId.trim(),
|
||||
project_id: projectId.trim(),
|
||||
correlation_id: correlationId.trim(),
|
||||
},
|
||||
}
|
||||
|
||||
return createAgnetDeployment({ orchestration_plan: plan })
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
toast.success(
|
||||
t('Agnet deployment created', {
|
||||
deployment_id: data.deployment_id,
|
||||
}) as string
|
||||
)
|
||||
void queryClient.invalidateQueries({ queryKey: ['agnet', 'deployments'] })
|
||||
onOpenChange(false)
|
||||
resetForm()
|
||||
},
|
||||
onError: (err: Error) => {
|
||||
const code = err.message
|
||||
if (code === 'sk_sources_must_be_array') {
|
||||
toast.error(t('Invalid SK sources JSON'))
|
||||
return
|
||||
}
|
||||
if (code === 'invalid_sk_sources_json') {
|
||||
toast.error(t('Invalid SK sources JSON'))
|
||||
return
|
||||
}
|
||||
if (code === 'profile_required_for_runtime') {
|
||||
toast.error(t('Execution profile required when cloud or network set'))
|
||||
return
|
||||
}
|
||||
toast.error(err.message || t('Deployment request failed'))
|
||||
},
|
||||
})
|
||||
|
||||
const canSubmit = useMemo(() => {
|
||||
return (
|
||||
templateHint.trim() &&
|
||||
objective.trim() &&
|
||||
tenantId.trim() &&
|
||||
projectId.trim() &&
|
||||
correlationId.trim() &&
|
||||
agents.every((a) => a.role_template.trim() && a.goal.trim())
|
||||
)
|
||||
}, [
|
||||
templateHint,
|
||||
objective,
|
||||
tenantId,
|
||||
projectId,
|
||||
correlationId,
|
||||
agents,
|
||||
])
|
||||
|
||||
const fillExampleSk = (index: number) => {
|
||||
setAgents((prev) => {
|
||||
const next = [...prev]
|
||||
next[index] = { ...next[index], sk_sources_json: DEFAULT_SK_JSON }
|
||||
return next
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Sheet open={open} onOpenChange={onOpenChange}>
|
||||
<SheetContent className='flex max-h-svh flex-col gap-0 overflow-hidden sm:max-w-xl'>
|
||||
<SheetHeader className='shrink-0 border-b pb-4'>
|
||||
<SheetTitle>{t('Create Agnet deployment')}</SheetTitle>
|
||||
<SheetDescription>
|
||||
{t('Create Agnet deployment description')}
|
||||
</SheetDescription>
|
||||
</SheetHeader>
|
||||
|
||||
<div className='flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto py-4'>
|
||||
<section className='space-y-3'>
|
||||
<p className='text-[11px] font-semibold uppercase tracking-[0.14em] text-muted-foreground'>
|
||||
{t('Deployment plan')}
|
||||
</p>
|
||||
<div className='grid gap-2'>
|
||||
<Label>{t('Template hint')}</Label>
|
||||
<Input
|
||||
value={templateHint}
|
||||
onChange={(e) => setTemplateHint(e.target.value)}
|
||||
className='font-mono text-xs'
|
||||
/>
|
||||
</div>
|
||||
<div className='grid gap-2'>
|
||||
<Label>{t('Objective')}</Label>
|
||||
<Textarea
|
||||
value={objective}
|
||||
onChange={(e) => setObjective(e.target.value)}
|
||||
rows={2}
|
||||
className='text-sm'
|
||||
/>
|
||||
</div>
|
||||
<div className='grid gap-2'>
|
||||
<Label>{t('Risk level')}</Label>
|
||||
<Select
|
||||
value={riskLevel}
|
||||
onValueChange={(v) =>
|
||||
setRiskLevel(v as 'low' | 'medium' | 'high')
|
||||
}
|
||||
>
|
||||
<SelectTrigger className='h-9'>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value='low'>low</SelectItem>
|
||||
<SelectItem value='medium'>medium</SelectItem>
|
||||
<SelectItem value='high'>high</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className='space-y-3'>
|
||||
<p className='text-[11px] font-semibold uppercase tracking-[0.14em] text-muted-foreground'>
|
||||
{t('Budget caps')}
|
||||
</p>
|
||||
<div className='grid grid-cols-3 gap-2'>
|
||||
<div>
|
||||
<Label className='text-xs'>{t('Max tokens')}</Label>
|
||||
<Input
|
||||
type='number'
|
||||
value={maxTokens}
|
||||
onChange={(e) => setMaxTokens(Number(e.target.value))}
|
||||
className='mt-1 h-9 text-xs'
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label className='text-xs'>{t('Max cost USD')}</Label>
|
||||
<Input
|
||||
type='number'
|
||||
step={0.01}
|
||||
value={maxCost}
|
||||
onChange={(e) => setMaxCost(Number(e.target.value))}
|
||||
className='mt-1 h-9 text-xs'
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label className='text-xs'>{t('Max duration sec')}</Label>
|
||||
<Input
|
||||
type='number'
|
||||
value={maxDurationSec}
|
||||
onChange={(e) => setMaxDurationSec(Number(e.target.value))}
|
||||
className='mt-1 h-9 text-xs'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className='space-y-3'>
|
||||
<p className='text-[11px] font-semibold uppercase tracking-[0.14em] text-muted-foreground'>
|
||||
{t('Metadata')}
|
||||
</p>
|
||||
<div className='grid gap-2 sm:grid-cols-2'>
|
||||
<div>
|
||||
<Label className='text-xs'>tenant_id</Label>
|
||||
<Input
|
||||
value={tenantId}
|
||||
onChange={(e) => setTenantId(e.target.value)}
|
||||
className='mt-1 font-mono text-xs'
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label className='text-xs'>project_id</Label>
|
||||
<Input
|
||||
value={projectId}
|
||||
onChange={(e) => setProjectId(e.target.value)}
|
||||
className='mt-1 font-mono text-xs'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className='grid gap-2'>
|
||||
<Label className='text-xs'>correlation_id</Label>
|
||||
<Input
|
||||
value={correlationId}
|
||||
onChange={(e) => setCorrelationId(e.target.value)}
|
||||
className='font-mono text-xs'
|
||||
/>
|
||||
</div>
|
||||
<div className='grid gap-2'>
|
||||
<Label className='text-xs'>{t('Allowed models comma')}</Label>
|
||||
<Input
|
||||
value={allowedModels}
|
||||
onChange={(e) => setAllowedModels(e.target.value)}
|
||||
placeholder='mdl_claude_sonnet, mdl_claude_haiku'
|
||||
className='font-mono text-xs'
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className='space-y-3'>
|
||||
<div className='flex items-center justify-between'>
|
||||
<p className='text-[11px] font-semibold uppercase tracking-[0.14em] text-muted-foreground'>
|
||||
{t('Agents')}
|
||||
</p>
|
||||
<Button
|
||||
type='button'
|
||||
variant='outline'
|
||||
size='sm'
|
||||
className='h-8 gap-1 text-xs'
|
||||
onClick={() => setAgents((a) => [...a, emptyAgent()])}
|
||||
>
|
||||
<Plus className='h-3.5 w-3.5' />
|
||||
{t('Add agent')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{agents.map((agent, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className='rounded-xl border border-[color-mix(in_oklch,var(--primary)_18%,var(--border))] bg-[color-mix(in_oklch,var(--card)_55%,transparent)] p-3'
|
||||
>
|
||||
<div className='mb-2 flex items-center justify-between'>
|
||||
<span className='text-xs font-medium'>
|
||||
{t('Agent')} #{index + 1}
|
||||
</span>
|
||||
{agents.length > 1 ? (
|
||||
<Button
|
||||
type='button'
|
||||
variant='ghost'
|
||||
size='icon'
|
||||
className='h-8 w-8'
|
||||
onClick={() =>
|
||||
setAgents((prev) => prev.filter((_, i) => i !== index))
|
||||
}
|
||||
>
|
||||
<Trash2 className='h-4 w-4 text-destructive' />
|
||||
</Button>
|
||||
) : null}
|
||||
</div>
|
||||
<div className='grid gap-2'>
|
||||
<Input
|
||||
placeholder={t('Role template')}
|
||||
value={agent.role_template}
|
||||
onChange={(e) =>
|
||||
setAgents((prev) => {
|
||||
const n = [...prev]
|
||||
n[index] = {
|
||||
...n[index],
|
||||
role_template: e.target.value,
|
||||
}
|
||||
return n
|
||||
})
|
||||
}
|
||||
className='font-mono text-xs'
|
||||
/>
|
||||
<Textarea
|
||||
placeholder={t('Goal')}
|
||||
value={agent.goal}
|
||||
onChange={(e) =>
|
||||
setAgents((prev) => {
|
||||
const n = [...prev]
|
||||
n[index] = { ...n[index], goal: e.target.value }
|
||||
return n
|
||||
})
|
||||
}
|
||||
rows={2}
|
||||
className='text-sm'
|
||||
/>
|
||||
<Input
|
||||
placeholder={t('Default model id')}
|
||||
value={agent.default_model_id}
|
||||
onChange={(e) =>
|
||||
setAgents((prev) => {
|
||||
const n = [...prev]
|
||||
n[index] = {
|
||||
...n[index],
|
||||
default_model_id: e.target.value,
|
||||
}
|
||||
return n
|
||||
})
|
||||
}
|
||||
className='font-mono text-xs'
|
||||
/>
|
||||
|
||||
<div className='flex items-center justify-between pt-1'>
|
||||
<Label className='text-xs'>{t('SK sources JSON')}</Label>
|
||||
<Button
|
||||
type='button'
|
||||
variant='ghost'
|
||||
size='sm'
|
||||
className='h-7 text-[11px]'
|
||||
onClick={() => fillExampleSk(index)}
|
||||
>
|
||||
{t('Insert git SK example')}
|
||||
</Button>
|
||||
</div>
|
||||
<Textarea
|
||||
value={agent.sk_sources_json}
|
||||
onChange={(e) =>
|
||||
setAgents((prev) => {
|
||||
const n = [...prev]
|
||||
n[index] = {
|
||||
...n[index],
|
||||
sk_sources_json: e.target.value,
|
||||
}
|
||||
return n
|
||||
})
|
||||
}
|
||||
spellCheck={false}
|
||||
className='min-h-[100px] font-mono text-[11px]'
|
||||
/>
|
||||
|
||||
<p className='text-[11px] font-semibold text-muted-foreground'>
|
||||
{t('Runtime binding')}
|
||||
</p>
|
||||
<Input
|
||||
placeholder={t('Execution profile')}
|
||||
value={agent.profile_id}
|
||||
onChange={(e) =>
|
||||
setAgents((prev) => {
|
||||
const n = [...prev]
|
||||
n[index] = { ...n[index], profile_id: e.target.value }
|
||||
return n
|
||||
})
|
||||
}
|
||||
className='font-mono text-xs'
|
||||
/>
|
||||
<Input
|
||||
placeholder={t('Cloud principals comma')}
|
||||
value={agent.cloud_principals}
|
||||
onChange={(e) =>
|
||||
setAgents((prev) => {
|
||||
const n = [...prev]
|
||||
n[index] = {
|
||||
...n[index],
|
||||
cloud_principals: e.target.value,
|
||||
}
|
||||
return n
|
||||
})
|
||||
}
|
||||
className='font-mono text-xs'
|
||||
/>
|
||||
<Input
|
||||
placeholder={t('Network policy')}
|
||||
value={agent.network_policy_ref}
|
||||
onChange={(e) =>
|
||||
setAgents((prev) => {
|
||||
const n = [...prev]
|
||||
n[index] = {
|
||||
...n[index],
|
||||
network_policy_ref: e.target.value,
|
||||
}
|
||||
return n
|
||||
})
|
||||
}
|
||||
className='font-mono text-xs'
|
||||
/>
|
||||
|
||||
<p className='text-[11px] font-semibold text-muted-foreground'>
|
||||
{t('SK access policy')}
|
||||
</p>
|
||||
<Input
|
||||
placeholder={t('Policy ref')}
|
||||
value={agent.policy_ref}
|
||||
onChange={(e) =>
|
||||
setAgents((prev) => {
|
||||
const n = [...prev]
|
||||
n[index] = { ...n[index], policy_ref: e.target.value }
|
||||
return n
|
||||
})
|
||||
}
|
||||
className='font-mono text-xs'
|
||||
/>
|
||||
<Input
|
||||
placeholder={t('Denied skills')}
|
||||
value={agent.deny_skill_ids}
|
||||
onChange={(e) =>
|
||||
setAgents((prev) => {
|
||||
const n = [...prev]
|
||||
n[index] = {
|
||||
...n[index],
|
||||
deny_skill_ids: e.target.value,
|
||||
}
|
||||
return n
|
||||
})
|
||||
}
|
||||
className='font-mono text-xs'
|
||||
/>
|
||||
<label className='flex items-center gap-2 text-xs'>
|
||||
<Checkbox
|
||||
checked={agent.inherit_defaults}
|
||||
onCheckedChange={(v) =>
|
||||
setAgents((prev) => {
|
||||
const n = [...prev]
|
||||
n[index] = {
|
||||
...n[index],
|
||||
inherit_defaults: Boolean(v),
|
||||
}
|
||||
return n
|
||||
})
|
||||
}
|
||||
/>
|
||||
{t('Inherits deployment defaults')}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<SheetFooter className='shrink-0 border-t pt-4'>
|
||||
<Button
|
||||
type='button'
|
||||
variant='outline'
|
||||
onClick={() => onOpenChange(false)}
|
||||
>
|
||||
{t('Cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
type='button'
|
||||
disabled={!canSubmit || mutation.isPending}
|
||||
onClick={() => mutation.mutate()}
|
||||
>
|
||||
{mutation.isPending ? (
|
||||
<Loader2 className='mr-2 h-4 w-4 animate-spin' />
|
||||
) : null}
|
||||
{t('Submit deployment')}
|
||||
</Button>
|
||||
</SheetFooter>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
)
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
GitCommit,
|
||||
Hash,
|
||||
PlayCircle,
|
||||
Plus,
|
||||
Rocket,
|
||||
Search,
|
||||
ShieldCheck,
|
||||
@@ -45,6 +46,7 @@ import {
|
||||
type AgnetRuntimeExecution,
|
||||
type AgnetSKAccessPolicy,
|
||||
} from './api'
|
||||
import { CreateAgnetDeploymentSheet } from './create-agnet-deployment-sheet'
|
||||
|
||||
type StatusKey = 'running' | 'success' | 'failed' | 'pending'
|
||||
|
||||
@@ -201,6 +203,7 @@ export function AgnetDeploymentsPage() {
|
||||
const { t } = useTranslation()
|
||||
const [filter, setFilter] = useState<'all' | StatusKey>('all')
|
||||
const [keyword, setKeyword] = useState('')
|
||||
const [createOpen, setCreateOpen] = useState(false)
|
||||
|
||||
const { data = [], isLoading } = useQuery({
|
||||
queryKey: ['agnet', 'deployments'],
|
||||
@@ -225,6 +228,7 @@ export function AgnetDeploymentsPage() {
|
||||
}, [data, filter, keyword])
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageSurface
|
||||
title={t('Deployments')}
|
||||
subtitle={t(
|
||||
@@ -232,6 +236,15 @@ export function AgnetDeploymentsPage() {
|
||||
)}
|
||||
toolbar={
|
||||
<>
|
||||
<Button
|
||||
type='button'
|
||||
size='sm'
|
||||
className='h-9 gap-1.5 rounded-xl'
|
||||
onClick={() => setCreateOpen(true)}
|
||||
>
|
||||
<Plus className='h-3.5 w-3.5' />
|
||||
{t('New deployment')}
|
||||
</Button>
|
||||
<div className='relative'>
|
||||
<Search className='pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground' />
|
||||
<Input
|
||||
@@ -332,6 +345,8 @@ export function AgnetDeploymentsPage() {
|
||||
</div>
|
||||
)}
|
||||
</PageSurface>
|
||||
<CreateAgnetDeploymentSheet open={createOpen} onOpenChange={setCreateOpen} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+26
-2
@@ -209,6 +209,30 @@
|
||||
"Policy ref": "Policy ref",
|
||||
"Denied skills": "Denied skills",
|
||||
"Inherits deployment defaults": "Inherits deployment defaults",
|
||||
"Add agent": "Add agent",
|
||||
"Agent": "Agent",
|
||||
"Agnet deployment created": "Agnet deployment created ({{deployment_id}})",
|
||||
"Allowed models comma": "Allowed model IDs (comma-separated)",
|
||||
"Budget caps": "Budget caps",
|
||||
"Cloud principals comma": "Cloud principals (comma-separated)",
|
||||
"Create Agnet deployment": "Create Agnet deployment",
|
||||
"Create Agnet deployment description": "Send the full orchestration plan in one request. Manager stores it; execution runs on Agnet.",
|
||||
"Default model id": "Default model ID",
|
||||
"Deployment plan": "Deployment plan",
|
||||
"Deployment request failed": "Deployment request failed",
|
||||
"Execution profile required when cloud or network set": "Set an execution profile when you configure cloud principals or a network policy.",
|
||||
"Goal": "Goal",
|
||||
"Insert git SK example": "Insert Git SK example",
|
||||
"Invalid SK sources JSON": "SK sources must be a valid JSON array",
|
||||
"Max cost USD": "Max cost (USD)",
|
||||
"Max duration sec": "Max duration (seconds)",
|
||||
"Max tokens": "Max tokens",
|
||||
"Objective": "Objective",
|
||||
"Risk level": "Risk level",
|
||||
"Role template": "Role template",
|
||||
"SK sources JSON": "SK sources (JSON)",
|
||||
"Submit deployment": "Submit deployment",
|
||||
"Template hint": "Template hint",
|
||||
"Aggregated usage metrics and trend charts.": "Aggregated usage metrics and trend charts.",
|
||||
"aggregates 50+ AI providers behind one unified API. Manage access, track costs, and scale effortlessly.": "aggregates 50+ AI providers behind one unified API. Manage access, track costs, and scale effortlessly.",
|
||||
"Agile Minimal": "Agile Minimal",
|
||||
@@ -1613,8 +1637,8 @@
|
||||
"Get Started": "Get Started",
|
||||
"Git binding": "Git binding",
|
||||
"Git sources": "Git sources",
|
||||
"Git sources binding explainer": "Skill (SK) definitions live in Git. Manager does not edit Markdown here—register code repos, SK tool repos, and refs via the Heicode client or your deployment plan sk_sources. Allocate cloud permissions for sub-agents (VMs, roles, scopes) in the same plan; deploy sub-agents after bindings exist so each run inherits allow/deny SK policy. Below lists immutable snapshot anchors (Git commit / upload artifact) resolved for auditing.",
|
||||
"Git sources subtitle": "Bind Git code and SK tool repositories, attach cloud permissions for sub-agents, deploy, then review snapshot anchors per deployment.",
|
||||
"Git sources binding explainer": "Skill (SK) definitions live in Git. Manager does not edit Markdown here—register code repos, SK tool repos, and refs via the Heicode client or your deployment plan sk_sources. Pass runtime and SK-policy parameters into Agnet when it starts each deployment; effective permissions are stored and enforced on Agnet. Below lists immutable snapshot anchors (Git commit / upload artifact) Agnet resolved for auditing.",
|
||||
"Git sources subtitle": "Configure bindings and deployment parameters for Agnet, then review snapshot anchors per deployment (enforcement lives on Agnet).",
|
||||
"Git sources workflow title": "Typical setup flow",
|
||||
"Git sources workflow step 1": "Bind your team’s Git repositories that hold application code and delivery context.",
|
||||
"Git sources workflow step 2": "Bind SK tool repositories (skills registry) your tenant is allowed to draw from.",
|
||||
|
||||
+26
-2
@@ -209,6 +209,30 @@
|
||||
"Policy ref": "Policy ref",
|
||||
"Denied skills": "Denied skills",
|
||||
"Inherits deployment defaults": "Inherits deployment defaults",
|
||||
"Add agent": "Add agent",
|
||||
"Agent": "Agent",
|
||||
"Agnet deployment created": "Agnet deployment created ({{deployment_id}})",
|
||||
"Allowed models comma": "Allowed model IDs (comma-separated)",
|
||||
"Budget caps": "Budget caps",
|
||||
"Cloud principals comma": "Cloud principals (comma-separated)",
|
||||
"Create Agnet deployment": "Create Agnet deployment",
|
||||
"Create Agnet deployment description": "Send the full orchestration plan in one request. Manager stores it; execution runs on Agnet.",
|
||||
"Default model id": "Default model ID",
|
||||
"Deployment plan": "Deployment plan",
|
||||
"Deployment request failed": "Deployment request failed",
|
||||
"Execution profile required when cloud or network set": "Set an execution profile when you configure cloud principals or a network policy.",
|
||||
"Goal": "Goal",
|
||||
"Insert git SK example": "Insert Git SK example",
|
||||
"Invalid SK sources JSON": "SK sources must be a valid JSON array",
|
||||
"Max cost USD": "Max cost (USD)",
|
||||
"Max duration sec": "Max duration (seconds)",
|
||||
"Max tokens": "Max tokens",
|
||||
"Objective": "Objective",
|
||||
"Risk level": "Risk level",
|
||||
"Role template": "Role template",
|
||||
"SK sources JSON": "SK sources (JSON)",
|
||||
"Submit deployment": "Submit deployment",
|
||||
"Template hint": "Template hint",
|
||||
"Aggregated usage metrics and trend charts.": "Métriques d'utilisation agrégées et graphiques de tendances.",
|
||||
"aggregates 50+ AI providers behind one unified API. Manage access, track costs, and scale effortlessly.": "agrège plus de 50 fournisseurs IA derrière une API unifiée. Gérez l'accès, suivez les coûts et évoluez sans effort.",
|
||||
"Agile Minimal": "Agile Minimal",
|
||||
@@ -1613,8 +1637,8 @@
|
||||
"Get Started": "Commencer",
|
||||
"Git binding": "Git binding",
|
||||
"Git sources": "Git sources",
|
||||
"Git sources binding explainer": "Skill (SK) definitions live in Git. Manager does not edit Markdown here—register code repos, SK tool repos, and refs via the Heicode client or your deployment plan sk_sources. Allocate cloud permissions for sub-agents (VMs, roles, scopes) in the same plan; deploy sub-agents after bindings exist so each run inherits allow/deny SK policy. Below lists immutable snapshot anchors (Git commit / upload artifact) resolved for auditing.",
|
||||
"Git sources subtitle": "Bind Git code and SK tool repositories, attach cloud permissions for sub-agents, deploy, then review snapshot anchors per deployment.",
|
||||
"Git sources binding explainer": "Skill (SK) definitions live in Git. Manager does not edit Markdown here—register code repos, SK tool repos, and refs via the Heicode client or your deployment plan sk_sources. Pass runtime and SK-policy parameters into Agnet when it starts each deployment; effective permissions are stored and enforced on Agnet. Below lists immutable snapshot anchors (Git commit / upload artifact) Agnet resolved for auditing.",
|
||||
"Git sources subtitle": "Configure bindings and deployment parameters for Agnet, then review snapshot anchors per deployment (enforcement lives on Agnet).",
|
||||
"Git sources workflow title": "Typical setup flow",
|
||||
"Git sources workflow step 1": "Bind your team’s Git repositories that hold application code and delivery context.",
|
||||
"Git sources workflow step 2": "Bind SK tool repositories (skills registry) your tenant is allowed to draw from.",
|
||||
|
||||
+26
-2
@@ -209,6 +209,30 @@
|
||||
"Policy ref": "Policy ref",
|
||||
"Denied skills": "Denied skills",
|
||||
"Inherits deployment defaults": "Inherits deployment defaults",
|
||||
"Add agent": "Add agent",
|
||||
"Agent": "Agent",
|
||||
"Agnet deployment created": "Agnet deployment created ({{deployment_id}})",
|
||||
"Allowed models comma": "Allowed model IDs (comma-separated)",
|
||||
"Budget caps": "Budget caps",
|
||||
"Cloud principals comma": "Cloud principals (comma-separated)",
|
||||
"Create Agnet deployment": "Create Agnet deployment",
|
||||
"Create Agnet deployment description": "Send the full orchestration plan in one request. Manager stores it; execution runs on Agnet.",
|
||||
"Default model id": "Default model ID",
|
||||
"Deployment plan": "Deployment plan",
|
||||
"Deployment request failed": "Deployment request failed",
|
||||
"Execution profile required when cloud or network set": "Set an execution profile when you configure cloud principals or a network policy.",
|
||||
"Goal": "Goal",
|
||||
"Insert git SK example": "Insert Git SK example",
|
||||
"Invalid SK sources JSON": "SK sources must be a valid JSON array",
|
||||
"Max cost USD": "Max cost (USD)",
|
||||
"Max duration sec": "Max duration (seconds)",
|
||||
"Max tokens": "Max tokens",
|
||||
"Objective": "Objective",
|
||||
"Risk level": "Risk level",
|
||||
"Role template": "Role template",
|
||||
"SK sources JSON": "SK sources (JSON)",
|
||||
"Submit deployment": "Submit deployment",
|
||||
"Template hint": "Template hint",
|
||||
"Aggregated usage metrics and trend charts.": "集計された使用量メトリクスとトレンドチャート。",
|
||||
"aggregates 50+ AI providers behind one unified API. Manage access, track costs, and scale effortlessly.": "50以上のAIプロバイダーを統一APIで集約。アクセス管理、コスト追跡、スケーリングを簡単に。",
|
||||
"Agile Minimal": "Agile Minimal",
|
||||
@@ -1613,8 +1637,8 @@
|
||||
"Get Started": "開始する",
|
||||
"Git binding": "Git binding",
|
||||
"Git sources": "Git sources",
|
||||
"Git sources binding explainer": "Skill (SK) definitions live in Git. Manager does not edit Markdown here—register code repos, SK tool repos, and refs via the Heicode client or your deployment plan sk_sources. Allocate cloud permissions for sub-agents (VMs, roles, scopes) in the same plan; deploy sub-agents after bindings exist so each run inherits allow/deny SK policy. Below lists immutable snapshot anchors (Git commit / upload artifact) resolved for auditing.",
|
||||
"Git sources subtitle": "Bind Git code and SK tool repositories, attach cloud permissions for sub-agents, deploy, then review snapshot anchors per deployment.",
|
||||
"Git sources binding explainer": "Skill (SK) definitions live in Git. Manager does not edit Markdown here—register code repos, SK tool repos, and refs via the Heicode client or your deployment plan sk_sources. Pass runtime and SK-policy parameters into Agnet when it starts each deployment; effective permissions are stored and enforced on Agnet. Below lists immutable snapshot anchors (Git commit / upload artifact) Agnet resolved for auditing.",
|
||||
"Git sources subtitle": "Configure bindings and deployment parameters for Agnet, then review snapshot anchors per deployment (enforcement lives on Agnet).",
|
||||
"Git sources workflow title": "Typical setup flow",
|
||||
"Git sources workflow step 1": "Bind your team’s Git repositories that hold application code and delivery context.",
|
||||
"Git sources workflow step 2": "Bind SK tool repositories (skills registry) your tenant is allowed to draw from.",
|
||||
|
||||
+26
-2
@@ -209,6 +209,30 @@
|
||||
"Policy ref": "Policy ref",
|
||||
"Denied skills": "Denied skills",
|
||||
"Inherits deployment defaults": "Inherits deployment defaults",
|
||||
"Add agent": "Add agent",
|
||||
"Agent": "Agent",
|
||||
"Agnet deployment created": "Agnet deployment created ({{deployment_id}})",
|
||||
"Allowed models comma": "Allowed model IDs (comma-separated)",
|
||||
"Budget caps": "Budget caps",
|
||||
"Cloud principals comma": "Cloud principals (comma-separated)",
|
||||
"Create Agnet deployment": "Create Agnet deployment",
|
||||
"Create Agnet deployment description": "Send the full orchestration plan in one request. Manager stores it; execution runs on Agnet.",
|
||||
"Default model id": "Default model ID",
|
||||
"Deployment plan": "Deployment plan",
|
||||
"Deployment request failed": "Deployment request failed",
|
||||
"Execution profile required when cloud or network set": "Set an execution profile when you configure cloud principals or a network policy.",
|
||||
"Goal": "Goal",
|
||||
"Insert git SK example": "Insert Git SK example",
|
||||
"Invalid SK sources JSON": "SK sources must be a valid JSON array",
|
||||
"Max cost USD": "Max cost (USD)",
|
||||
"Max duration sec": "Max duration (seconds)",
|
||||
"Max tokens": "Max tokens",
|
||||
"Objective": "Objective",
|
||||
"Risk level": "Risk level",
|
||||
"Role template": "Role template",
|
||||
"SK sources JSON": "SK sources (JSON)",
|
||||
"Submit deployment": "Submit deployment",
|
||||
"Template hint": "Template hint",
|
||||
"Aggregated usage metrics and trend charts.": "Агрегированные метрики использования и графики трендов.",
|
||||
"aggregates 50+ AI providers behind one unified API. Manage access, track costs, and scale effortlessly.": "объединяет 50+ ИИ-провайдеров за единым API. Управляйте доступом, отслеживайте затраты и масштабируйтесь без усилий.",
|
||||
"Agile Minimal": "Agile Minimal",
|
||||
@@ -1613,8 +1637,8 @@
|
||||
"Get Started": "Начать",
|
||||
"Git binding": "Git binding",
|
||||
"Git sources": "Git sources",
|
||||
"Git sources binding explainer": "Skill (SK) definitions live in Git. Manager does not edit Markdown here—register code repos, SK tool repos, and refs via the Heicode client or your deployment plan sk_sources. Allocate cloud permissions for sub-agents (VMs, roles, scopes) in the same plan; deploy sub-agents after bindings exist so each run inherits allow/deny SK policy. Below lists immutable snapshot anchors (Git commit / upload artifact) resolved for auditing.",
|
||||
"Git sources subtitle": "Bind Git code and SK tool repositories, attach cloud permissions for sub-agents, deploy, then review snapshot anchors per deployment.",
|
||||
"Git sources binding explainer": "Skill (SK) definitions live in Git. Manager does not edit Markdown here—register code repos, SK tool repos, and refs via the Heicode client or your deployment plan sk_sources. Pass runtime and SK-policy parameters into Agnet when it starts each deployment; effective permissions are stored and enforced on Agnet. Below lists immutable snapshot anchors (Git commit / upload artifact) Agnet resolved for auditing.",
|
||||
"Git sources subtitle": "Configure bindings and deployment parameters for Agnet, then review snapshot anchors per deployment (enforcement lives on Agnet).",
|
||||
"Git sources workflow title": "Typical setup flow",
|
||||
"Git sources workflow step 1": "Bind your team’s Git repositories that hold application code and delivery context.",
|
||||
"Git sources workflow step 2": "Bind SK tool repositories (skills registry) your tenant is allowed to draw from.",
|
||||
|
||||
+26
-2
@@ -209,6 +209,30 @@
|
||||
"Policy ref": "Policy ref",
|
||||
"Denied skills": "Denied skills",
|
||||
"Inherits deployment defaults": "Inherits deployment defaults",
|
||||
"Add agent": "Add agent",
|
||||
"Agent": "Agent",
|
||||
"Agnet deployment created": "Agnet deployment created ({{deployment_id}})",
|
||||
"Allowed models comma": "Allowed model IDs (comma-separated)",
|
||||
"Budget caps": "Budget caps",
|
||||
"Cloud principals comma": "Cloud principals (comma-separated)",
|
||||
"Create Agnet deployment": "Create Agnet deployment",
|
||||
"Create Agnet deployment description": "Send the full orchestration plan in one request. Manager stores it; execution runs on Agnet.",
|
||||
"Default model id": "Default model ID",
|
||||
"Deployment plan": "Deployment plan",
|
||||
"Deployment request failed": "Deployment request failed",
|
||||
"Execution profile required when cloud or network set": "Set an execution profile when you configure cloud principals or a network policy.",
|
||||
"Goal": "Goal",
|
||||
"Insert git SK example": "Insert Git SK example",
|
||||
"Invalid SK sources JSON": "SK sources must be a valid JSON array",
|
||||
"Max cost USD": "Max cost (USD)",
|
||||
"Max duration sec": "Max duration (seconds)",
|
||||
"Max tokens": "Max tokens",
|
||||
"Objective": "Objective",
|
||||
"Risk level": "Risk level",
|
||||
"Role template": "Role template",
|
||||
"SK sources JSON": "SK sources (JSON)",
|
||||
"Submit deployment": "Submit deployment",
|
||||
"Template hint": "Template hint",
|
||||
"Aggregated usage metrics and trend charts.": "Chỉ số sử dụng tổng hợp và biểu đồ xu hướng.",
|
||||
"aggregates 50+ AI providers behind one unified API. Manage access, track costs, and scale effortlessly.": "tổng hợp hơn 50 nhà cung cấp AI sau một API thống nhất. Quản lý truy cập, theo dõi chi phí và mở rộng dễ dàng.",
|
||||
"Agile Minimal": "Agile Minimal",
|
||||
@@ -1613,8 +1637,8 @@
|
||||
"Get Started": "Bắt đầu",
|
||||
"Git binding": "Git binding",
|
||||
"Git sources": "Git sources",
|
||||
"Git sources binding explainer": "Skill (SK) definitions live in Git. Manager does not edit Markdown here—register code repos, SK tool repos, and refs via the Heicode client or your deployment plan sk_sources. Allocate cloud permissions for sub-agents (VMs, roles, scopes) in the same plan; deploy sub-agents after bindings exist so each run inherits allow/deny SK policy. Below lists immutable snapshot anchors (Git commit / upload artifact) resolved for auditing.",
|
||||
"Git sources subtitle": "Bind Git code and SK tool repositories, attach cloud permissions for sub-agents, deploy, then review snapshot anchors per deployment.",
|
||||
"Git sources binding explainer": "Skill (SK) definitions live in Git. Manager does not edit Markdown here—register code repos, SK tool repos, and refs via the Heicode client or your deployment plan sk_sources. Pass runtime and SK-policy parameters into Agnet when it starts each deployment; effective permissions are stored and enforced on Agnet. Below lists immutable snapshot anchors (Git commit / upload artifact) Agnet resolved for auditing.",
|
||||
"Git sources subtitle": "Configure bindings and deployment parameters for Agnet, then review snapshot anchors per deployment (enforcement lives on Agnet).",
|
||||
"Git sources workflow title": "Typical setup flow",
|
||||
"Git sources workflow step 1": "Bind your team’s Git repositories that hold application code and delivery context.",
|
||||
"Git sources workflow step 2": "Bind SK tool repositories (skills registry) your tenant is allowed to draw from.",
|
||||
|
||||
+26
-2
@@ -209,6 +209,30 @@
|
||||
"Policy ref": "策略引用",
|
||||
"Denied skills": "禁止的技能",
|
||||
"Inherits deployment defaults": "继承部署默认策略",
|
||||
"Add agent": "添加 Agent",
|
||||
"Agent": "Agent",
|
||||
"Agnet deployment created": "Agnet 部署已创建({{deployment_id}})",
|
||||
"Allowed models comma": "允许的模型 ID(逗号分隔)",
|
||||
"Budget caps": "预算上限",
|
||||
"Cloud principals comma": "云身份引用(逗号分隔)",
|
||||
"Create Agnet deployment": "创建 Agnet 部署",
|
||||
"Create Agnet deployment description": "在一次请求中提交完整编排计划。Manager 负责记录;实际执行在 Agnet。",
|
||||
"Default model id": "默认模型 ID",
|
||||
"Deployment plan": "编排计划",
|
||||
"Deployment request failed": "部署请求失败",
|
||||
"Execution profile required when cloud or network set": "填写云身份或网络策略时,请同时设置执行档案。",
|
||||
"Goal": "Agent 目标",
|
||||
"Insert git SK example": "插入 Git SK 示例",
|
||||
"Invalid SK sources JSON": "SK 来源须为有效的 JSON 数组",
|
||||
"Max cost USD": "最大费用(USD)",
|
||||
"Max duration sec": "最长时长(秒)",
|
||||
"Max tokens": "最大 token 数",
|
||||
"Objective": "计划目标",
|
||||
"Risk level": "风险等级",
|
||||
"Role template": "角色模板",
|
||||
"SK sources JSON": "SK 来源(JSON)",
|
||||
"Submit deployment": "提交部署",
|
||||
"Template hint": "模板提示",
|
||||
"Aggregated usage metrics and trend charts.": "聚合使用指标和趋势图表。",
|
||||
"aggregates 50+ AI providers behind one unified API. Manage access, track costs, and scale effortlessly.": "聚合 50+ AI 提供商于统一 API 之后。轻松管理访问、追踪成本、弹性扩展。",
|
||||
"Agile Minimal": "敏捷最小编队",
|
||||
@@ -1613,8 +1637,8 @@
|
||||
"Get Started": "开始使用",
|
||||
"Git binding": "Git 绑定",
|
||||
"Git sources": "Git 来源",
|
||||
"Git sources binding explainer": "Skill(SK)定义以 Git 为唯一事实源。Manager 不在此编辑 Markdown:请在 Heicode 客户端或部署计划的 sk_sources 中登记代码仓库、SK 工具仓库与引用;并在同一计划中为子 Agent 分配云上权限(虚拟机、角色、API 范围等)。完成绑定后再部署子 Agent,使每次运行继承允许的 SK 与被禁止的 SK 策略。下列为运行时解析得到的不可变快照锚点(Git commit / 上传制品),供审计追溯。",
|
||||
"Git sources subtitle": "绑定代码与 SK 工具仓库、为子 Agent 分配云上权限并部署后,在此按部署查看快照锚点。",
|
||||
"Git sources binding explainer": "Skill(SK)定义以 Git 为唯一事实源。Manager 不在此编辑 Markdown:请在 Heicode 客户端或部署计划的 sk_sources 中登记仓库与引用;运行时与 SK 策略等参数在 Agnet 拉起编队/子 Agent 时传入。有效权限与策略落账在 Agnet 侧并由其执行;Manager 仅展示 Agnet 回传的不可变快照锚点(Git commit / 上传制品)供审计。",
|
||||
"Git sources subtitle": "在部署参数中把绑定与策略交给 Agnet,在此按部署查看快照锚点(执行权在 Agnet)。",
|
||||
"Git sources workflow title": "典型配置顺序",
|
||||
"Git sources workflow step 1": "绑定团队用于应用代码与交付上下文的 Git 仓库。",
|
||||
"Git sources workflow step 2": "绑定 SK 工具仓库(技能来源),声明租户可引用的工具集。",
|
||||
|
||||
Reference in New Issue
Block a user