@pasko70/pibo 3.0.2 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compute-image/Dockerfile +47 -0
- package/compute-image/Dockerfile.dockerignore +5 -0
- package/dist/agent-runtime/contract.js +78 -28
- package/dist/agent-runtime/portable-history.js +19 -9
- package/dist/agent-runtime/registry.js +8 -2
- package/dist/agent-runtime/routed-session.js +12 -6
- package/dist/agent-runtimes/pi/routed-session.js +10 -4
- package/dist/apps/chat/agent-store.js +55 -3
- package/dist/apps/chat/data/project-service.js +119 -15
- package/dist/apps/chat/data/room-service.js +21 -0
- package/dist/apps/chat/loop-api.js +10 -2
- package/dist/apps/chat/web-app.js +84 -25
- package/dist/apps/chat-ui/assets/{dist-CvaPTBTN.js → dist-CUQJqggN.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BPotHecb.js → dist-ClUlQWYN.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BzqQKeVO.js → dist-Djul9BmZ.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-paagejNj.js → dist-GD0JGdCi.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-B6GZgWSj.js → dist-W5HOqHym.js} +1 -1
- package/dist/apps/chat-ui/assets/index-BcjkX-iP.js +228 -0
- package/dist/apps/chat-ui/assets/index-CmqRSbBU.css +1 -0
- package/dist/apps/chat-ui/index.html +2 -2
- package/dist/apps/chat-vscode-web/assets/index-JvrPUGvI.js +43 -0
- package/dist/apps/chat-vscode-web/index.html +1 -1
- package/dist/apps/cli-ui/InkSessionApp.js +111 -12
- package/dist/compute/cli.js +35 -16
- package/dist/compute/docker.js +341 -94
- package/dist/config/config.js +3 -0
- package/dist/core/output-render-sequence.js +148 -1
- package/dist/core/session-router.js +33 -105
- package/dist/data/ingest-service.js +14 -6
- package/dist/data/pibo-store.js +8 -1
- package/dist/data/schema.js +135 -5
- package/dist/debug/agents.js +91 -89
- package/dist/debug/index.js +2 -0
- package/dist/debug/pty.js +127 -48
- package/dist/gateway/cli.js +4 -0
- package/dist/loops/channel.js +3 -1
- package/dist/loops/cli.js +2 -1
- package/dist/loops/service.js +90 -11
- package/dist/loops/store.js +100 -74
- package/dist/mcp/agent-context.js +13 -26
- package/dist/mcp/commands/info.js +3 -1
- package/dist/mcp/config-command.js +46 -2
- package/dist/mcp/config.js +18 -4
- package/dist/plugins/context-files-store.js +6 -6
- package/dist/previews/base-url.js +34 -0
- package/dist/previews/config.js +2 -32
- package/dist/ralph/store.js +5 -0
- package/dist/reliability/store.js +174 -111
- package/dist/session-ui/terminalRows.js +2 -1
- package/dist/sessions/pibo-data-store.js +81 -0
- package/dist/subagents/observation-query.js +121 -0
- package/dist/tools/agent-browser-leases.js +58 -23
- package/dist/tools/agent-browser-wrapper.js +1 -1
- package/dist/tools/browser-use-leases.js +129 -16
- package/dist/tools/browser-use-wrapper.js +1 -1
- package/dist/tools/index.js +27 -11
- package/dist/tools/python-runtime.js +10 -3
- package/dist/tools/registry.js +1 -1
- package/dist/tools/runtime/node-backend.js +16 -5
- package/dist/tools/runtime/node-worker-source.js +112 -33
- package/dist/tools/runtime/python-backend.js +16 -5
- package/dist/tools/runtime/python-worker-source.js +167 -16
- package/dist/tools/runtime/registry.js +23 -10
- package/dist/user-skills/store.js +0 -1
- package/npm-shrinkwrap.json +9 -2
- package/package.json +8 -2
- package/scripts/docker-entrypoint.sh +46 -0
- package/scripts/prepare-agent-browser-wrapper.sh +70 -0
- package/scripts/prepare-browser-use-wrapper.sh +255 -0
- package/dist/apps/chat-ui/assets/index-6JJV-eic.js +0 -228
- package/dist/apps/chat-ui/assets/index-CeL9JPP5.css +0 -1
- package/dist/apps/chat-vscode-web/assets/index-U-MSErGa.js +0 -43
|
@@ -2,7 +2,7 @@ import { PiboWebHttpError, readJsonBody, responseJson } from '../../web/http.js'
|
|
|
2
2
|
import { getPiboLoopService } from '../../loops/channel.js';
|
|
3
3
|
import { listLoopJobTemplates } from '../../loops/templates.js';
|
|
4
4
|
import { isPiboThinkingLevel } from '../../core/thinking.js';
|
|
5
|
-
import { normalizeLoopStopPolicy } from '../../loops/store.js';
|
|
5
|
+
import { normalizeLoopStopPolicy, PiboLoopActiveRunModeChangeError } from '../../loops/store.js';
|
|
6
6
|
import { isPiboRoomArchived } from './types/rooms.js';
|
|
7
7
|
const CHAT_WEB_API_PREFIX = '/api/chat';
|
|
8
8
|
function requireSameOriginJsonRequest(request) { const contentType = request.headers.get('content-type')?.split(';')[0]?.trim().toLowerCase(); if (contentType !== 'application/json')
|
|
@@ -184,7 +184,15 @@ export async function handleChatLoopApiRequest(options) {
|
|
|
184
184
|
throw new PiboWebHttpError('Loop job not found', 404);
|
|
185
185
|
if ((patch.mode ?? existing.mode) === 'ralph' && ((patch.tokenBudget !== undefined && patch.tokenBudget !== null) || (patch.tokenReserve !== undefined && patch.tokenReserve !== null)))
|
|
186
186
|
throw new PiboWebHttpError('tokenBudget and tokenReserve are only available for goal mode', 400);
|
|
187
|
-
|
|
187
|
+
let job;
|
|
188
|
+
try {
|
|
189
|
+
job = loopStore.updateJob(resource.id, patch);
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
if (error instanceof PiboLoopActiveRunModeChangeError)
|
|
193
|
+
throw new PiboWebHttpError(error.message, 409);
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
188
196
|
if (!job)
|
|
189
197
|
throw new PiboWebHttpError('Loop job not found', 404);
|
|
190
198
|
return responseJson({ job: serializeJob(job) });
|
|
@@ -19,7 +19,7 @@ import { DEFAULT_TRACE_EVENTS_PAGE_SIZE, annotateTracePage, etagForVersion, esti
|
|
|
19
19
|
import { TRACE_V2_DEFAULT_TIMELINE_LIMIT, TRACE_V2_MAX_TIMELINE_LIMIT, TRACE_V2_PAYLOAD_DEFAULT_LIMIT_BYTES, TRACE_V2_PAYLOAD_MAX_LIMIT_BYTES, TRACE_V2_RAW_EVENTS_DEFAULT_LIMIT, TRACE_V2_RAW_EVENTS_MAX_LIMIT, TRACE_V2_TIMELINE_HARD_BYTES, TRACE_IMAGE_MAX_COUNT, parseTracePayloadRef, readTraceImagePayload, readTracePayloadChunk, traceRawEventsPageFromEvents, traceTimelinePageFromView, } from "./trace-v2.js";
|
|
20
20
|
import { isChatWebSessionArchived } from "./session-metadata.js";
|
|
21
21
|
import { withWorkflowSessionKind } from "../../sessions/workflow-session-kind.js";
|
|
22
|
-
import { CustomAgentStore, createDefaultCustomAgentStore, previewCustomAgentCreate, previewCustomAgentUpdate, } from "./agent-store.js";
|
|
22
|
+
import { CustomAgentTargetReferenceError, CustomAgentStore, createDefaultCustomAgentStore, previewCustomAgentCreate, previewCustomAgentUpdate, } from "./agent-store.js";
|
|
23
23
|
import { loadPiboModelDefaults, } from "../../core/model-defaults.js";
|
|
24
24
|
import { inspectPiboContextBuild } from "../../core/context-build.js";
|
|
25
25
|
import { isPiboThinkingLevel } from "../../core/thinking.js";
|
|
@@ -35,7 +35,7 @@ import { ScopedUserSkillManager } from "../../user-skills/manager.js";
|
|
|
35
35
|
import { ChatDataIngestService, outputIdempotencyKey, outputPersistenceDeliveryKey } from "../../data/ingest-service.js";
|
|
36
36
|
import { ChatEventCommandService } from "./data/event-command-service.js";
|
|
37
37
|
import { ChatReadStateService } from "./data/read-state-service.js";
|
|
38
|
-
import { ChatRoomService } from "./data/room-service.js";
|
|
38
|
+
import { ChatRoomService, PiboRoomHierarchyCycleError } from "./data/room-service.js";
|
|
39
39
|
import { ChatSessionQueryService } from "./data/session-query-service.js";
|
|
40
40
|
import { ChatTimelineQueryService } from "./data/timeline-query-service.js";
|
|
41
41
|
import { ChatHistoryQueryService } from "./data/history-query-service.js";
|
|
@@ -2352,6 +2352,17 @@ function normalizeAgentDeleteConfirmation(value) {
|
|
|
2352
2352
|
}
|
|
2353
2353
|
return value.trim();
|
|
2354
2354
|
}
|
|
2355
|
+
function requireCustomAgentNotTargeted(state, agent, options = {}) {
|
|
2356
|
+
const dependents = state.agentStore.listReferencingAgents(agent.id)
|
|
2357
|
+
.filter((dependent) => !options.activeOnly || !dependent.archivedAt);
|
|
2358
|
+
if (dependents.length === 0)
|
|
2359
|
+
return;
|
|
2360
|
+
const error = new CustomAgentTargetReferenceError(agent.profileName, dependents.map((dependent) => dependent.profileName));
|
|
2361
|
+
const message = options.activeOnly
|
|
2362
|
+
? error.message.replace("targeted by custom agents", "targeted by active custom agents")
|
|
2363
|
+
: error.message;
|
|
2364
|
+
throw new PiboWebHttpError(message, 409);
|
|
2365
|
+
}
|
|
2355
2366
|
async function deleteSessionsForAgentProfile(state, context, webSession, profileNames) {
|
|
2356
2367
|
const deleteSession = context.channelContext.deleteSession;
|
|
2357
2368
|
if (!deleteSession)
|
|
@@ -2371,10 +2382,11 @@ async function deleteSessionsForAgentProfile(state, context, webSession, profile
|
|
|
2371
2382
|
}
|
|
2372
2383
|
}
|
|
2373
2384
|
const orderedIds = [...ids].sort((left, right) => sessionDepth(sessionsById.get(right), sessionsById) - sessionDepth(sessionsById.get(left), sessionsById));
|
|
2374
|
-
for (const id of orderedIds)
|
|
2375
|
-
await deleteSession(id);
|
|
2376
|
-
|
|
2377
|
-
|
|
2385
|
+
for (const id of orderedIds) {
|
|
2386
|
+
await state.projectService.deleteProjectSessionWithCanonicalDelete(id, () => deleteSession(id));
|
|
2387
|
+
state.sessionQuery.deleteSessions([id]);
|
|
2388
|
+
state.eventCommands.deleteSessions([id]);
|
|
2389
|
+
}
|
|
2378
2390
|
for (const id of orderedIds)
|
|
2379
2391
|
disposeSessionStreamState(state, id);
|
|
2380
2392
|
return orderedIds;
|
|
@@ -2397,10 +2409,11 @@ async function deleteSessionSubtree(state, context, webSession, rootSession) {
|
|
|
2397
2409
|
}
|
|
2398
2410
|
}
|
|
2399
2411
|
const orderedIds = [...ids].sort((left, right) => sessionDepth(sessionsById.get(right), sessionsById) - sessionDepth(sessionsById.get(left), sessionsById));
|
|
2400
|
-
for (const id of orderedIds)
|
|
2401
|
-
await deleteSession(id);
|
|
2402
|
-
|
|
2403
|
-
|
|
2412
|
+
for (const id of orderedIds) {
|
|
2413
|
+
await state.projectService.deleteProjectSessionWithCanonicalDelete(id, () => deleteSession(id));
|
|
2414
|
+
state.sessionQuery.deleteSessions([id]);
|
|
2415
|
+
state.eventCommands.deleteSessions([id]);
|
|
2416
|
+
}
|
|
2404
2417
|
for (const id of orderedIds)
|
|
2405
2418
|
disposeSessionStreamState(state, id);
|
|
2406
2419
|
return orderedIds;
|
|
@@ -2437,10 +2450,11 @@ async function deleteRoomTree(state, context, webSession, room, confirmName) {
|
|
|
2437
2450
|
}
|
|
2438
2451
|
}
|
|
2439
2452
|
const orderedSessionIds = [...ids].sort((left, right) => sessionDepth(sessionsById.get(right), sessionsById) - sessionDepth(sessionsById.get(left), sessionsById));
|
|
2440
|
-
for (const id of orderedSessionIds)
|
|
2441
|
-
await deleteSession(id);
|
|
2442
|
-
|
|
2443
|
-
|
|
2453
|
+
for (const id of orderedSessionIds) {
|
|
2454
|
+
await state.projectService.deleteProjectSessionWithCanonicalDelete(id, () => deleteSession(id));
|
|
2455
|
+
state.sessionQuery.deleteSessions([id]);
|
|
2456
|
+
state.eventCommands.deleteSessions([id]);
|
|
2457
|
+
}
|
|
2444
2458
|
for (const id of orderedSessionIds)
|
|
2445
2459
|
disposeSessionStreamState(state, id);
|
|
2446
2460
|
state.eventCommands.deleteRooms(roomIds);
|
|
@@ -3961,7 +3975,9 @@ export function createChatWebApp(options = {}) {
|
|
|
3961
3975
|
const webSession = await requireSession(request, context);
|
|
3962
3976
|
const body = await readJsonBody(request);
|
|
3963
3977
|
try {
|
|
3964
|
-
requireSharedProject(state, webSession, projectResource.projectId, { includeArchived: true });
|
|
3978
|
+
const existingProject = requireSharedProject(state, webSession, projectResource.projectId, { includeArchived: true });
|
|
3979
|
+
if (existingProject.metadata.default === true)
|
|
3980
|
+
throw new PiboWebHttpError("Project Manager cannot be changed", 400);
|
|
3965
3981
|
const project = state.projectService.updateProject(projectResource.projectId, {
|
|
3966
3982
|
...(body.name !== undefined ? { name: normalizeRoomName(body.name) } : {}),
|
|
3967
3983
|
...(body.description !== undefined ? { description: normalizeProjectDescription(body.description) ?? null } : {}),
|
|
@@ -3982,7 +3998,9 @@ export function createChatWebApp(options = {}) {
|
|
|
3982
3998
|
const webSession = await requireSession(request, context);
|
|
3983
3999
|
const body = await readJsonBody(request);
|
|
3984
4000
|
try {
|
|
3985
|
-
requireSharedProject(state, webSession, projectResource.projectId, { includeArchived: true });
|
|
4001
|
+
const project = requireSharedProject(state, webSession, projectResource.projectId, { includeArchived: true });
|
|
4002
|
+
if (project.metadata.default === true)
|
|
4003
|
+
throw new PiboWebHttpError("Project Manager cannot be deleted", 400);
|
|
3986
4004
|
return responseJson(state.projectService.deleteProject(projectResource.projectId, {
|
|
3987
4005
|
confirmName: normalizeRoomDeleteConfirmation(body.confirmName),
|
|
3988
4006
|
deleteFiles: body.deleteFiles === true,
|
|
@@ -4272,22 +4290,43 @@ export function createChatWebApp(options = {}) {
|
|
|
4272
4290
|
if (!rootPiboSessionId)
|
|
4273
4291
|
throw new PiboWebHttpError("rootPiboSessionId is required", 400);
|
|
4274
4292
|
requireSharedSession(context, rootPiboSessionId);
|
|
4275
|
-
|
|
4293
|
+
const includeStatuses = parseBooleanSearchParam(url, "includeStatuses");
|
|
4294
|
+
if (!context.channelContext.snapshotSignalTree
|
|
4295
|
+
|| !context.channelContext.subscribeSignalTree
|
|
4296
|
+
|| (includeStatuses && (!context.channelContext.snapshotSignalStatuses || !context.channelContext.subscribeSignalStatuses))) {
|
|
4276
4297
|
throw new PiboWebHttpError("Signal registry is not available", 503);
|
|
4277
4298
|
}
|
|
4278
|
-
let
|
|
4299
|
+
let unsubscribeTree;
|
|
4300
|
+
let unsubscribeStatuses;
|
|
4279
4301
|
let heartbeat;
|
|
4302
|
+
let closed = false;
|
|
4280
4303
|
const stream = new ReadableStream({
|
|
4281
4304
|
start: (controller) => {
|
|
4282
4305
|
writeJsonSse(controller, "signal_snapshot", context.channelContext.snapshotSignalTree(rootPiboSessionId));
|
|
4283
|
-
|
|
4284
|
-
|
|
4306
|
+
unsubscribeTree = context.channelContext.subscribeSignalTree(rootPiboSessionId, (patch) => {
|
|
4307
|
+
if (!closed)
|
|
4308
|
+
writeJsonSse(controller, "signal_patch", patch, String(patch.toVersion));
|
|
4285
4309
|
});
|
|
4286
|
-
|
|
4310
|
+
if (includeStatuses) {
|
|
4311
|
+
writeJsonSse(controller, "signal_status_snapshot", context.channelContext.snapshotSignalStatuses());
|
|
4312
|
+
unsubscribeStatuses = context.channelContext.subscribeSignalStatuses((patch) => {
|
|
4313
|
+
if (closed)
|
|
4314
|
+
return;
|
|
4315
|
+
const statusPatch = compactSignalStatusPatch(patch);
|
|
4316
|
+
writeJsonSse(controller, "signal_status_patch", statusPatch, `${patch.rootPiboSessionId}:${patch.toVersion}`);
|
|
4317
|
+
});
|
|
4318
|
+
}
|
|
4319
|
+
heartbeat = setInterval(() => {
|
|
4320
|
+
if (!closed)
|
|
4321
|
+
writeSseComment(controller, "heartbeat");
|
|
4322
|
+
}, 25_000);
|
|
4287
4323
|
},
|
|
4288
4324
|
cancel: () => {
|
|
4289
|
-
|
|
4290
|
-
|
|
4325
|
+
closed = true;
|
|
4326
|
+
unsubscribeTree?.();
|
|
4327
|
+
unsubscribeTree = undefined;
|
|
4328
|
+
unsubscribeStatuses?.();
|
|
4329
|
+
unsubscribeStatuses = undefined;
|
|
4291
4330
|
if (heartbeat)
|
|
4292
4331
|
clearInterval(heartbeat);
|
|
4293
4332
|
heartbeat = undefined;
|
|
@@ -4691,6 +4730,9 @@ export function createChatWebApp(options = {}) {
|
|
|
4691
4730
|
if (customAgentUpdateAffectsRuntime(update)) {
|
|
4692
4731
|
await requireValidCustomAgentRuntime(previewCustomAgentUpdate(existing, update), context);
|
|
4693
4732
|
}
|
|
4733
|
+
if (archived === true && !existing.archivedAt) {
|
|
4734
|
+
requireCustomAgentNotTargeted(state, existing, { activeOnly: true });
|
|
4735
|
+
}
|
|
4694
4736
|
const updated = Object.keys(update).length ? state.agentStore.update(patchAgentId, update) : existing;
|
|
4695
4737
|
const afterUpdate = requireSharedAgent(updated);
|
|
4696
4738
|
const agent = archived === undefined ? afterUpdate : state.agentStore.setArchived(patchAgentId, archived);
|
|
@@ -4717,8 +4759,16 @@ export function createChatWebApp(options = {}) {
|
|
|
4717
4759
|
if (confirmName !== agent.profileName) {
|
|
4718
4760
|
throw new PiboWebHttpError(`Type "${agent.profileName}" to permanently delete this agent and its sessions.`, 400);
|
|
4719
4761
|
}
|
|
4762
|
+
requireCustomAgentNotTargeted(state, agent);
|
|
4720
4763
|
const deletedSessionIds = await deleteSessionsForAgentProfile(state, context, webSession, [agent.profileName, ...agent.profileAliases]);
|
|
4721
|
-
|
|
4764
|
+
try {
|
|
4765
|
+
state.agentStore.delete(agent.id);
|
|
4766
|
+
}
|
|
4767
|
+
catch (error) {
|
|
4768
|
+
if (error instanceof CustomAgentTargetReferenceError)
|
|
4769
|
+
throw new PiboWebHttpError(error.message, 409);
|
|
4770
|
+
throw error;
|
|
4771
|
+
}
|
|
4722
4772
|
context.channelContext.removeProfile?.(agent.profileName);
|
|
4723
4773
|
invalidateBootstrapCatalogCache(state);
|
|
4724
4774
|
return responseJson({ deletedAgentId: agent.id, deletedSessionIds });
|
|
@@ -4829,7 +4879,16 @@ export function createChatWebApp(options = {}) {
|
|
|
4829
4879
|
const update = createRoomUpdate(existingRoom, body);
|
|
4830
4880
|
if (update.parentRoomId)
|
|
4831
4881
|
requireRoom(state, update.parentRoomId, webSession, "admin");
|
|
4832
|
-
|
|
4882
|
+
let room;
|
|
4883
|
+
try {
|
|
4884
|
+
room = state.roomService.updateRoom(roomResource.roomId, update);
|
|
4885
|
+
}
|
|
4886
|
+
catch (error) {
|
|
4887
|
+
if (error instanceof PiboRoomHierarchyCycleError) {
|
|
4888
|
+
throw new PiboWebHttpError(error.message, 400);
|
|
4889
|
+
}
|
|
4890
|
+
throw error;
|
|
4891
|
+
}
|
|
4833
4892
|
if (!room)
|
|
4834
4893
|
throw new PiboWebHttpError("Room not found", 404);
|
|
4835
4894
|
return responseJson({ room });
|