feat: optimze skill and tool
This commit is contained in:
@@ -65,7 +65,7 @@ export function presentDefineCall(args: {
|
||||
return {
|
||||
card: 'generic',
|
||||
kind: 'execute',
|
||||
title: `Define Package "${args.name}" for ${target}: ${args.purpose}`,
|
||||
title: `Register Cordis Plugin "${args.name}" for ${target}: ${args.purpose}`,
|
||||
rawInput: args.code,
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ export function presentDefineCall(args: {
|
||||
* @returns replay-safe generic call presentation.
|
||||
*/
|
||||
export function presentUndefineCall(args: { pluginId: string }): GenericCallView {
|
||||
return { card: 'generic', kind: 'delete', title: `Remove dynamic Plugin ${args.pluginId}` }
|
||||
return { card: 'generic', kind: 'delete', title: `Remove Cordis Plugin ${args.pluginId}` }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,7 +88,7 @@ export function presentRunCall(args: { pluginId: string; packageId: string; mode
|
||||
return {
|
||||
card: 'generic',
|
||||
kind: 'execute',
|
||||
title: `${args.mode === 'update' ? 'Update' : 'Run'} ${args.pluginId} · ${args.packageId}`,
|
||||
title: `${args.mode === 'update' ? 'Update' : 'Run'} Cordis Plugin ${args.pluginId} · ${args.packageId}`,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,5 +98,5 @@ export function presentRunCall(args: { pluginId: string; packageId: string; mode
|
||||
* @returns replay-safe generic call presentation.
|
||||
*/
|
||||
export function presentStopCall(args: { pluginId: string }): GenericCallView {
|
||||
return { card: 'generic', kind: 'execute', title: `Stop dynamic Plugin ${args.pluginId}` }
|
||||
return { card: 'generic', kind: 'execute', title: `Stop Cordis Plugin ${args.pluginId}` }
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/** Localized cards for `cordis_stop` and `cordis_undefine`. */
|
||||
|
||||
import {
|
||||
IconInspectOutline12, IconStopFill16, IconTrashOutline16, StateDot,
|
||||
} from '@deepseek-ai/dsh-client-ui-primitives'
|
||||
import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'
|
||||
import type { ToolCallViewProps } from '@deepseek-ai/dsh-client-ui-tool/client'
|
||||
import { cordisActionCard } from './card-model.ts'
|
||||
import css from './CordisRunRow.module.css'
|
||||
|
||||
/** Full action-card props composed by the keyed Tool slot. */
|
||||
export type CordisActionRowProps = ToolCallViewProps & PropsLocale<'cordis'>
|
||||
|
||||
/** Render one Stop or Remove call with Cordis-owned localized copy. */
|
||||
export function CordisActionRow({ callId, toolName, block, inspect, t }: CordisActionRowProps) {
|
||||
const card = cordisActionCard(block)
|
||||
const remove = toolName === 'cordis_undefine'
|
||||
const summary = card.errorSummary ?? card.pluginId ?? callId
|
||||
|
||||
return (
|
||||
<div className={css.card} data-tool={toolName} data-state={card.state}>
|
||||
<div className={css.row}>
|
||||
<span className={css.icon}>
|
||||
{card.state === 'error'
|
||||
? <StateDot state="error" />
|
||||
: card.state === 'stopped'
|
||||
? <StateDot state="warning" />
|
||||
: remove ? <IconTrashOutline16 size={14} /> : <IconStopFill16 size={14} />}
|
||||
</span>
|
||||
<span className={css.title}>{t(remove ? 'row.removeTitle' : 'row.stopTitle')}</span>
|
||||
<span className={css.separator} aria-hidden />
|
||||
<span className={card.errorSummary === null ? css.summary : css.error}>{summary}</span>
|
||||
{inspect !== undefined && (
|
||||
<button type="button" className={css.inspect} aria-label="Inspect" onClick={inspect}>
|
||||
<IconInspectOutline12 />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{card.output !== null && <pre className={css.output}>{card.output}</pre>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/** Replay-stable view models for `cordis_define` and `cordis_run` calls. */
|
||||
/** Replay-stable view models for Cordis lifecycle Tool calls. */
|
||||
|
||||
import type { ToolCallViewProps } from '@deepseek-ai/dsh-client-ui-tool/client'
|
||||
import type {
|
||||
@@ -35,6 +35,14 @@ export interface CordisRunCard {
|
||||
readonly state: CordisToolState
|
||||
}
|
||||
|
||||
/** Frozen `cordis_stop` or `cordis_undefine` presentation data. */
|
||||
export interface CordisActionCard {
|
||||
readonly pluginId: CordisDynamicPluginId | null
|
||||
readonly output: string | null
|
||||
readonly errorSummary: string | null
|
||||
readonly state: CordisToolState
|
||||
}
|
||||
|
||||
function firstLine(text: string): string {
|
||||
const newline = text.indexOf('\n')
|
||||
return newline === -1 ? text : text.slice(0, newline)
|
||||
@@ -132,3 +140,22 @@ export function cordisRunCard(block: Block): CordisRunCard {
|
||||
state,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive one Stop or Remove card from its frozen call/result slice.
|
||||
* @param block - active or settled tool-call block.
|
||||
* @returns normalized lifecycle-action card fields.
|
||||
*/
|
||||
export function cordisActionCard(block: Block): CordisActionCard {
|
||||
const settled = 'kind' in block
|
||||
const argsRaw = (settled ? block.call?.argsRaw : block.argsRaw) ?? ''
|
||||
const args = parseArgs(argsRaw)
|
||||
const state = stateOf(block)
|
||||
const output = settled ? resultText(block) : null
|
||||
return {
|
||||
pluginId: (args === null ? null : stringAt(args, 'pluginId') ?? stringAt(args, 'id')) as CordisDynamicPluginId | null,
|
||||
output,
|
||||
errorSummary: state === 'error' && output !== null ? firstLine(output) : null,
|
||||
state,
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import type {} from '@deepseek-ai/dsh-client-ui-sidebar/client'
|
||||
import type {} from '@deepseek-ai/dsh-api-remotes/client'
|
||||
import type { InputTriggerService, InputTriggerSource } from '@deepseek-ai/dsh-client-ui-input-trigger/client'
|
||||
import type {} from './events.ts'
|
||||
import { CordisActionRow } from './CordisActionRow.tsx'
|
||||
import { CordisDefineRow } from './CordisDefineRow.tsx'
|
||||
import { CordisRunRow } from './CordisRunRow.tsx'
|
||||
import { CordisPanel } from './CordisPanel.tsx'
|
||||
@@ -19,6 +20,7 @@ import { en, NS, zh } from './locales.ts'
|
||||
export type { CordisCardFace, CordisPanelFace, CordisRunCardFace, CordisToolViewOwnerProps } from './slots.ts'
|
||||
export type { CordisActionResult, CordisDynamicPort, CordisInventoryRow } from './dynamic-port.ts'
|
||||
export type { CordisDefineRowProps } from './CordisDefineRow.tsx'
|
||||
export type { CordisActionRowProps } from './CordisActionRow.tsx'
|
||||
export type { CordisRunRowProps } from './CordisRunRow.tsx'
|
||||
export type {
|
||||
CordisRunCardPointer, CordisRunCardStore, CordisToolViewKey,
|
||||
@@ -131,6 +133,15 @@ export function apply(ctx: ClientContext): void {
|
||||
},
|
||||
}, CordisRunRow))
|
||||
|
||||
ctx.slots.inject('tool.call.toolview', function* () {
|
||||
yield ctx.slots.register({
|
||||
name: 'tool.call.toolview', key: 'cordis_stop', locale: NS,
|
||||
}, CordisActionRow)
|
||||
yield ctx.slots.register({
|
||||
name: 'tool.call.toolview', key: 'cordis_undefine', locale: NS,
|
||||
}, CordisActionRow)
|
||||
})
|
||||
|
||||
const rowsOf = (sessionId: SessionId, query: string) => inventory.getSnapshot().rows
|
||||
.filter(row => row.agentId === sessionId && String(row.pluginId).includes(query))
|
||||
const source: InputTriggerSource = {
|
||||
|
||||
@@ -7,6 +7,8 @@ export const zh = {
|
||||
'row.defineTitle': '注册 Cordis 插件',
|
||||
'row.runTitle': '运行 Cordis 插件',
|
||||
'row.updateTitle': '更新 Cordis 插件',
|
||||
'row.stopTitle': '停止 Cordis 插件',
|
||||
'row.removeTitle': '移除 Cordis 插件',
|
||||
'purpose.missing': '(未填写用途)',
|
||||
'status.idle': '待激活',
|
||||
'status.awaitingApproval': '待审批',
|
||||
@@ -65,9 +67,11 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
|
||||
|
||||
/** English Cordis UI messages. */
|
||||
export const en = {
|
||||
'row.defineTitle': 'Define Cordis Plugin',
|
||||
'row.defineTitle': 'Register Cordis Plugin',
|
||||
'row.runTitle': 'Run Cordis Plugin',
|
||||
'row.updateTitle': 'Update Cordis Plugin',
|
||||
'row.stopTitle': 'Stop Cordis Plugin',
|
||||
'row.removeTitle': 'Remove Cordis Plugin',
|
||||
'purpose.missing': '(no purpose given)',
|
||||
'status.idle': 'Ready',
|
||||
'status.awaitingApproval': 'Awaiting approval',
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import type { RunningToolCall, ToolResultNode } from '@deepseek-ai/dsh-client-runtime/client'
|
||||
import { cordisDefineCard } from '../src/client/card-model.ts'
|
||||
import { cordisActionCard, cordisDefineCard } from '../src/client/card-model.ts'
|
||||
|
||||
const ARGS = '{"name":"clock","purpose":"顶栏时钟","code":{"client":"return {}","host":"harness.handle(\'now\', () => Date.now())"}}'
|
||||
|
||||
@@ -86,3 +86,20 @@ describe('cordisDefineCard', () => {
|
||||
expect(card.purpose).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe('cordisActionCard', () => {
|
||||
it('keeps the Plugin identity and lifecycle result for Stop and Remove cards', () => {
|
||||
const card = cordisActionCard(settled({
|
||||
call: { name: 'cordis_stop', argsRaw: '{"pluginId":"clock-1"}' },
|
||||
content: [{ type: 'text', text: 'Stopped clock-1.' }],
|
||||
meta: undefined,
|
||||
}))
|
||||
|
||||
expect(card).toEqual({
|
||||
pluginId: 'clock-1',
|
||||
output: 'Stopped clock-1.',
|
||||
errorSummary: null,
|
||||
state: 'ok',
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user