feat(stage-ui,airi-plugin-vscode,server-shared): added spark:notify, spark:emit, spark:command events
This commit is contained in:
@@ -55,6 +55,15 @@ export interface ContextUpdate<
|
||||
// eslint-disable-next-line ts/no-unnecessary-type-constraint
|
||||
Content extends any = undefined,
|
||||
> {
|
||||
id: string
|
||||
/**
|
||||
* Can be the same if same update sends multiple time as attempts
|
||||
* and trials, (e.g. notified first but not ACKed, then retried).
|
||||
*/
|
||||
contextId: string
|
||||
lane?: string
|
||||
ideas?: Array<string>
|
||||
hints?: Array<string>
|
||||
strategy: ContextUpdateStrategy
|
||||
text: string
|
||||
content?: Content
|
||||
@@ -132,6 +141,93 @@ export interface WebSocketEvents<C = undefined> {
|
||||
}
|
||||
} & Partial<WithInputSource<'stage-web' | 'stage-tamagotchi' | 'discord'>> & Partial<WithOutputSource<'gen-ai:chat'>>
|
||||
|
||||
/**
|
||||
* Sub-agent raises an event toward the character (or other destinations).
|
||||
* Examples:
|
||||
* - Minecraft attack/death: kind=alarm, urgency=immediate (fast bubble-up).
|
||||
* e.g., fromAgent='minecraft', headline='Under attack by witch', payload includes hp/location/gear.
|
||||
* - Cat bowl empty from HomeAssistant: kind=alarm, urgency=soon.
|
||||
* - IM/email "read now": kind=ping, urgency=immediate.
|
||||
* - Action Required email: kind=reminder, urgency=later.
|
||||
* destinations controls routing (e.g. ['character'], ['character','minecraft-agent']).
|
||||
*/
|
||||
'spark:notify': {
|
||||
id: string
|
||||
eventId: string
|
||||
lane?: string
|
||||
kind: 'alarm' | 'ping' | 'reminder'
|
||||
urgency: 'immediate' | 'soon' | 'later'
|
||||
headline: string
|
||||
note?: string
|
||||
payload?: Record<string, unknown>
|
||||
ttlMs?: number
|
||||
requiresAck?: boolean
|
||||
destinations: Array<string>
|
||||
}
|
||||
|
||||
/**
|
||||
* Acknowledgement/progress/state for a spark or command (bidirectional).
|
||||
* Examples:
|
||||
* - Character: state=working, note="Seen it, responding".
|
||||
* - Sub-agent: state=done, note="Healed and safe".
|
||||
* - Sub-agent: state=blocked/dropped with note when it cannot comply.
|
||||
* - Minecraft: state=working, note="Pillared up; healing" in reply to a command.
|
||||
*/
|
||||
'spark:emit': {
|
||||
id: string
|
||||
eventId?: string
|
||||
state: 'queued' | 'working' | 'done' | 'dropped' | 'blocked' | 'expired'
|
||||
note?: string
|
||||
destinations: Array<string>
|
||||
}
|
||||
|
||||
/**
|
||||
* Character issues instructions or context to a sub-agent.
|
||||
* interrupt: force = hard preempt; soft = merge/queue.
|
||||
* Examples:
|
||||
* - Witch attack: interrupt=force, priority=critical, intent=action with options (aggressive/cautious).
|
||||
* e.g., options to block/retreat vs push with shield/sword, with fallback steps.
|
||||
* - Prep plan: interrupt=soft, priority=high, intent=plan with steps/fallbacks.
|
||||
* - Contextual hints: intent=context with contextPatch ideas/hints.
|
||||
*/
|
||||
'spark:command': {
|
||||
id: string
|
||||
eventId?: string
|
||||
parentEventId?: string
|
||||
commandId: string
|
||||
interrupt: 'force' | 'soft' | false
|
||||
priority: 'critical' | 'high' | 'normal' | 'low'
|
||||
intent: 'action' | 'plan' | 'pause' | 'resume' | 'reroute' | 'context'
|
||||
ack?: string
|
||||
guidance?: {
|
||||
type: 'proposal' | 'instruction' | 'memory-recall'
|
||||
/**
|
||||
* Personas can be used to adjust the behavior of sub-agents.
|
||||
* For example, when using as NPC in games, or player in Minecraft,
|
||||
* the persona can help define the character's traits and decision-making style.
|
||||
*
|
||||
* Example:
|
||||
* persona: {
|
||||
* "bravery": "high",
|
||||
* "cautiousness": "low",
|
||||
* "friendliness": "medium"
|
||||
* }
|
||||
*/
|
||||
persona?: Record<string, 'very-high' | 'high' | 'medium' | 'low' | 'very-low'>
|
||||
options: Array<{
|
||||
label: string
|
||||
steps: Array<string>
|
||||
rationale?: string
|
||||
possibleOutcome?: Array<string>
|
||||
risk?: 'high' | 'medium' | 'low' | 'none'
|
||||
fallback?: Array<string>
|
||||
triggers?: Array<string>
|
||||
}>
|
||||
}
|
||||
contexts?: Array<ContextUpdate>
|
||||
destinations: Array<string>
|
||||
}
|
||||
|
||||
'context:update': ContextUpdate
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { ContextUpdate, WebSocketBaseEvent, WebSocketEvent, WebSocketEventO
|
||||
|
||||
import { Client, WebSocketEventSource } from '@proj-airi/server-sdk'
|
||||
import { isStageTamagotchi, isStageWeb } from '@proj-airi/stage-shared'
|
||||
import { nanoid } from 'nanoid'
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
@@ -97,8 +98,9 @@ export const useModsServerChannelStore = defineStore('mods:channels:proj-airi:se
|
||||
}
|
||||
}
|
||||
|
||||
function sendContextUpdate(message: ContextUpdate) {
|
||||
send({ type: 'context:update', data: message })
|
||||
function sendContextUpdate(message: Omit<ContextUpdate, 'id' | 'contextId'> & Partial<Pick<ContextUpdate, 'id' | 'contextId'>>) {
|
||||
const id = nanoid()
|
||||
send({ type: 'context:update', data: { id, contextId: id, ...message } })
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
|
||||
@@ -89,7 +89,7 @@ export const useContextBridgeStore = defineStore('mods:api:context-bridge', () =
|
||||
broadcastStreamEvent({ type: 'assistant-end', message, sessionId: chatStore.activeSessionId, context })
|
||||
}),
|
||||
|
||||
chatStore.onAssistantMessage(async (message, messageText, context) => {
|
||||
chatStore.onAssistantMessage(async (message, _messageText, context) => {
|
||||
serverChannelStore.send({
|
||||
type: 'output:gen-ai:chat:message',
|
||||
data: {
|
||||
|
||||
@@ -68,7 +68,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"es-toolkit": "catalog:",
|
||||
"injeca": "catalog:"
|
||||
"injeca": "catalog:",
|
||||
"nanoid": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@guiiai/logg": "catalog:",
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { Events } from './types'
|
||||
|
||||
import { useLogger } from '@guiiai/logg'
|
||||
import { ContextUpdateStrategy, Client as ServerClient } from '@proj-airi/server-sdk'
|
||||
import { nanoid } from 'nanoid'
|
||||
|
||||
export class Client {
|
||||
private client: ServerClient<Events> | null = null
|
||||
@@ -45,11 +46,13 @@ export class Client {
|
||||
}
|
||||
|
||||
async replaceContext(context: string): Promise<void> {
|
||||
this.send({ type: 'context:update', data: { strategy: ContextUpdateStrategy.ReplaceSelf, text: context } })
|
||||
const id = nanoid()
|
||||
this.send({ type: 'context:update', data: { strategy: ContextUpdateStrategy.ReplaceSelf, text: context, id, contextId: id } })
|
||||
}
|
||||
|
||||
async appendContext(context: string): Promise<void> {
|
||||
this.send({ type: 'context:update', data: { strategy: ContextUpdateStrategy.AppendSelf, text: context } })
|
||||
const id = nanoid()
|
||||
this.send({ type: 'context:update', data: { strategy: ContextUpdateStrategy.AppendSelf, text: context, id, contextId: id } })
|
||||
}
|
||||
|
||||
isConnected(): boolean {
|
||||
|
||||
Generated
+6
@@ -72,6 +72,9 @@ catalogs:
|
||||
injeca:
|
||||
specifier: ^0.1.5
|
||||
version: 0.1.5
|
||||
nanoid:
|
||||
specifier: ^5.1.6
|
||||
version: 5.1.6
|
||||
posthog-js:
|
||||
specifier: 1.306.1
|
||||
version: 1.306.1
|
||||
@@ -2089,6 +2092,9 @@ importers:
|
||||
injeca:
|
||||
specifier: 'catalog:'
|
||||
version: 0.1.5(@guiiai/logg@1.2.11)(error-stack-parser@2.1.4)(nanoid@5.1.6)
|
||||
nanoid:
|
||||
specifier: 'catalog:'
|
||||
version: 5.1.6
|
||||
devDependencies:
|
||||
'@guiiai/logg':
|
||||
specifier: 'catalog:'
|
||||
|
||||
+15
-13
@@ -1,6 +1,3 @@
|
||||
catalogMode: prefer
|
||||
|
||||
shellEmulator: true
|
||||
packages:
|
||||
- packages/**
|
||||
- plugins/**
|
||||
@@ -10,16 +7,6 @@ packages:
|
||||
- apps/**
|
||||
- '!**/dist/**'
|
||||
|
||||
overrides:
|
||||
array-flatten: npm:@nolyfill/array-flatten@^1.0.44
|
||||
axios: npm:feaxios@^0.0.23
|
||||
is-core-module: npm:@nolyfill/is-core-module@^1.0.39
|
||||
isarray: npm:@nolyfill/isarray@^1.0.44
|
||||
safe-buffer: npm:@nolyfill/safe-buffer@^1.0.44
|
||||
safer-buffer: npm:@nolyfill/safer-buffer@^1.0.44
|
||||
side-channel: npm:@nolyfill/side-channel@^1.0.44
|
||||
string.prototype.matchall: npm:@nolyfill/string.prototype.matchall@^1.0.44
|
||||
|
||||
catalog:
|
||||
'@guiiai/logg': ^1.2.11
|
||||
'@moeru/eslint-config': 0.1.0-beta.14
|
||||
@@ -43,11 +30,14 @@ catalog:
|
||||
embla-carousel-vue: ^8.6.0
|
||||
es-toolkit: 1.43.0
|
||||
injeca: ^0.1.5
|
||||
nanoid: ^5.1.6
|
||||
posthog-js: 1.306.1
|
||||
uncrypto: ^0.1.3
|
||||
unplugin-info: 1.2.4
|
||||
xsschema: ^0.4.0-beta.12
|
||||
|
||||
catalogMode: prefer
|
||||
|
||||
catalogs:
|
||||
rolldown-vite:
|
||||
vite: npm:rolldown-vite@^7.3.0
|
||||
@@ -76,3 +66,15 @@ onlyBuiltDependencies:
|
||||
- spawn-sync
|
||||
- utf-8-validate
|
||||
- vue-demi
|
||||
|
||||
overrides:
|
||||
array-flatten: npm:@nolyfill/array-flatten@^1.0.44
|
||||
axios: npm:feaxios@^0.0.23
|
||||
is-core-module: npm:@nolyfill/is-core-module@^1.0.39
|
||||
isarray: npm:@nolyfill/isarray@^1.0.44
|
||||
safe-buffer: npm:@nolyfill/safe-buffer@^1.0.44
|
||||
safer-buffer: npm:@nolyfill/safer-buffer@^1.0.44
|
||||
side-channel: npm:@nolyfill/side-channel@^1.0.44
|
||||
string.prototype.matchall: npm:@nolyfill/string.prototype.matchall@^1.0.44
|
||||
|
||||
shellEmulator: true
|
||||
|
||||
Reference in New Issue
Block a user